@helpers4/number 2.0.0-alpha.9 → 2.0.0-beta.3

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.
package/README.md CHANGED
@@ -13,17 +13,26 @@ A set of helpers for working with URLs.
13
13
 
14
14
  <!-- AUTOMATIC-METHODS -->
15
15
  - clamp
16
+ - formatCompact
17
+ - formatSize
18
+ - inRange
19
+ - lerp
20
+ - mean
16
21
  - random
17
22
  - roundTo
23
+ - sum
18
24
  <!-- /AUTOMATIC-METHODS -->
19
25
 
20
26
  ## See
21
27
 
22
28
  <!-- AUTOMATIC-SIBLINGS -->
23
29
  - [array](../array)
30
+ - [ci](../ci)
31
+ - [commit](../commit)
24
32
  - [date](../date)
25
33
  - [function](../function)
26
- - [math](../math)
34
+ - [id](../id)
35
+ - [markdown](../markdown)
27
36
  - [object](../object)
28
37
  - [observable](../observable)
29
38
  - [promise](../promise)
@@ -39,15 +48,18 @@ A set of helpers for working with URLs.
39
48
  | Name | Package | Source Code | Description |
40
49
  |------|---------|-------------|-------------|
41
50
  | array | [@helpers4/array](https://www.npmjs.com/package/@helpers4/array) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/array) | Array manipulation utilities |
42
- | date | [@helpers4/date](https://www.npmjs.com/package/@helpers4/date) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/date) | date utilities |
51
+ | ci | [@helpers4/ci](https://www.npmjs.com/package/@helpers4/ci) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/ci) | CI/CD workflow status utilities |
52
+ | commit | [@helpers4/commit](https://www.npmjs.com/package/@helpers4/commit) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/commit) | Conventional Commits parsing and analysis |
53
+ | date | [@helpers4/date](https://www.npmjs.com/package/@helpers4/date) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/date) | Date and time utility functions |
43
54
  | function | [@helpers4/function](https://www.npmjs.com/package/@helpers4/function) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/function) | Function utilities and type guards |
44
- | math | [@helpers4/math](https://www.npmjs.com/package/@helpers4/math) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/math) | math utilities |
45
- | number | [@helpers4/number](https://www.npmjs.com/package/@helpers4/number) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/number) | number utilities |
55
+ | id | [@helpers4/id](https://www.npmjs.com/package/@helpers4/id) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/id) | Unique identifier generation utilities |
56
+ | markdown | [@helpers4/markdown](https://www.npmjs.com/package/@helpers4/markdown) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/markdown) | Markdown formatting and escaping utilities |
57
+ | number | [@helpers4/number](https://www.npmjs.com/package/@helpers4/number) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/number) | Number utility functions and validation |
46
58
  | object | [@helpers4/object](https://www.npmjs.com/package/@helpers4/object) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/object) | Object manipulation utilities |
47
59
  | observable | [@helpers4/observable](https://www.npmjs.com/package/@helpers4/observable) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/observable) | Observable utilities and combinators |
48
60
  | promise | [@helpers4/promise](https://www.npmjs.com/package/@helpers4/promise) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/promise) | Promise utilities and error handling |
49
61
  | string | [@helpers4/string](https://www.npmjs.com/package/@helpers4/string) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/string) | String manipulation and formatting utilities |
50
- | type | [@helpers4/type](https://www.npmjs.com/package/@helpers4/type) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/type) | type utilities |
62
+ | type | [@helpers4/type](https://www.npmjs.com/package/@helpers4/type) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/type) | Type checking and validation utilities |
51
63
  | url | [@helpers4/url](https://www.npmjs.com/package/@helpers4/url) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/url) | URL parsing and manipulation utilities |
52
64
  | version | [@helpers4/version](https://www.npmjs.com/package/@helpers4/version) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/version) | Version string manipulation utilities |
53
65
  <!-- /AUTOMATIC-CATEGORIES-TABLE -->
package/lib/index.d.ts CHANGED
@@ -13,6 +13,134 @@
13
13
  */
14
14
  declare function clamp(value: number, min: number, max: number): number;
15
15
 
16
+ /**
17
+ * This file is part of helpers4.
18
+ * Copyright (C) 2025 baxyz
19
+ * SPDX-License-Identifier: LGPL-3.0-or-later
20
+ */
21
+ /**
22
+ * Formats a number using compact notation (e.g. `1_500_000 → "1.5M"`).
23
+ *
24
+ * Thin wrapper over `Intl.NumberFormat` with `notation: 'compact'`. Companion
25
+ * of `formatSize` in the same `format*` family.
26
+ *
27
+ * @param value - The number to format.
28
+ * @param locale - BCP 47 locale tag. Defaults to the runtime locale.
29
+ * @returns A compact string representation of the number.
30
+ * @example
31
+ * formatCompact(1_500_000); // '1.5M' (en-US locale)
32
+ * formatCompact(1_000); // '1K'
33
+ * formatCompact(999); // '999'
34
+ * formatCompact(1_500_000, 'fr'); // '1,5 M'
35
+ * @since next
36
+ */
37
+ declare function formatCompact(value: number, locale?: string): string;
38
+
39
+ /**
40
+ * This file is part of helpers4.
41
+ * Copyright (C) 2025 baxyz
42
+ * SPDX-License-Identifier: LGPL-3.0-or-later
43
+ */
44
+ /**
45
+ * Format a byte count into a human-readable string with the appropriate unit.
46
+ *
47
+ * Each unit is 1024 of the previous (binary prefix). The result is formatted
48
+ * with one decimal place.
49
+ *
50
+ * @param bytes - A non-negative integer representing a byte count.
51
+ * @returns A human-readable string such as `'0.0B'`, `'1.5KB'`, `'3.2MB'`.
52
+ * @example
53
+ * formatSize(0) // '0.0B'
54
+ * formatSize(512) // '512.0B'
55
+ * formatSize(1024) // '1.0KB'
56
+ * formatSize(1536) // '1.5KB'
57
+ * formatSize(1_048_576) // '1.0MB'
58
+ * formatSize(1_073_741_824) // '1.0GB'
59
+ * @since next
60
+ */
61
+ declare function formatSize(bytes: number): string;
62
+
63
+ /**
64
+ * This file is part of helpers4.
65
+ * Copyright (C) 2025 baxyz
66
+ * SPDX-License-Identifier: LGPL-3.0-or-later
67
+ */
68
+ /**
69
+ * Options for {@link inRange}.
70
+ */
71
+ interface InRangeOptions {
72
+ /**
73
+ * Which boundary (or boundaries) are included in the range.
74
+ * - `'both'` (default): `min <= value <= max`
75
+ * - `'min'`: `min <= value < max`
76
+ * - `'max'`: `min < value <= max`
77
+ * - `'none'`: `min < value < max`
78
+ */
79
+ inclusive?: 'both' | 'min' | 'max' | 'none';
80
+ }
81
+ /**
82
+ * Checks whether a number falls within `[min, max]` (both inclusive by default).
83
+ *
84
+ * @param value - The number to test
85
+ * @param min - Lower bound
86
+ * @param max - Upper bound
87
+ * @param options - Boundary inclusion mode (default: `'both'`)
88
+ * @returns `true` if `value` is within the specified range
89
+ * @example
90
+ * inRange(5, 1, 10) // => true
91
+ * inRange(1, 1, 10) // => true (min inclusive)
92
+ * inRange(1, 1, 10, { inclusive: 'none' }) // => false
93
+ * inRange(10, 1, 10, { inclusive: 'max' }) // => true
94
+ * @since next
95
+ */
96
+ declare function inRange(value: number, min: number, max: number, options?: InRangeOptions): boolean;
97
+
98
+ /**
99
+ * This file is part of helpers4.
100
+ * Copyright (C) 2025 baxyz
101
+ * SPDX-License-Identifier: LGPL-3.0-or-later
102
+ */
103
+ /**
104
+ * Linearly interpolates between `start` and `end` by the factor `t`.
105
+ *
106
+ * - `t = 0` returns `start`.
107
+ * - `t = 1` returns `end`.
108
+ * - Values of `t` outside `[0, 1]` extrapolate beyond the range.
109
+ *
110
+ * @param start - The start value.
111
+ * @param end - The end value.
112
+ * @param t - The interpolation factor.
113
+ * @returns The interpolated value.
114
+ * @example
115
+ * lerp(0, 100, 0); // 0
116
+ * lerp(0, 100, 1); // 100
117
+ * lerp(0, 100, 0.5); // 50
118
+ * lerp(0, 100, 0.25); // 25
119
+ * @since next
120
+ */
121
+ declare function lerp(start: number, end: number, t: number): number;
122
+
123
+ /**
124
+ * This file is part of helpers4.
125
+ * Copyright (C) 2025 baxyz
126
+ * SPDX-License-Identifier: LGPL-3.0-or-later
127
+ */
128
+ /**
129
+ * Calculates the arithmetic mean (average) of an array of numbers.
130
+ * Returns `NaN` for an empty array.
131
+ *
132
+ * Pairs with {@link sum} for aggregate operations.
133
+ *
134
+ * @param array - The array of numbers to average
135
+ * @returns The arithmetic mean, or `NaN` if the array is empty
136
+ * @example
137
+ * mean([1, 2, 3, 4]) // => 2.5
138
+ * mean([10]) // => 10
139
+ * mean([]) // => NaN
140
+ * @since next
141
+ */
142
+ declare function mean(array: readonly number[]): number;
143
+
16
144
  /**
17
145
  * This file is part of helpers4.
18
146
  * Copyright (C) 2025 baxyz
@@ -49,4 +177,21 @@ declare function randomIntBetween(min: number, max: number): number;
49
177
  */
50
178
  declare function roundTo(value: number, decimals: number): number;
51
179
 
52
- export { clamp, randomBetween, randomIntBetween, roundTo };
180
+ /**
181
+ * This file is part of helpers4.
182
+ * Copyright (C) 2025 baxyz
183
+ * SPDX-License-Identifier: LGPL-3.0-or-later
184
+ */
185
+ /**
186
+ * Calculates the sum of an array of numbers.
187
+ * @param array - The array of numbers to sum
188
+ * @returns The sum of all values
189
+ * @example
190
+ * sum([1, 2, 3, 4])
191
+ * // => 10
192
+ * @since 2.0.0
193
+ */
194
+ declare function sum(array: readonly number[]): number;
195
+
196
+ export { clamp, formatCompact, formatSize, inRange, lerp, mean, randomBetween, randomIntBetween, roundTo, sum };
197
+ export type { InRangeOptions };
package/lib/index.js CHANGED
@@ -16,6 +16,150 @@ function clamp(value, min, max) {
16
16
  return Math.min(Math.max(value, min), max);
17
17
  }
18
18
  //#endregion
19
+ //#region helpers/number/formatCompact.ts
20
+ /**
21
+ * This file is part of helpers4.
22
+ * Copyright (C) 2025 baxyz
23
+ * SPDX-License-Identifier: LGPL-3.0-or-later
24
+ */
25
+ /**
26
+ * Formats a number using compact notation (e.g. `1_500_000 → "1.5M"`).
27
+ *
28
+ * Thin wrapper over `Intl.NumberFormat` with `notation: 'compact'`. Companion
29
+ * of `formatSize` in the same `format*` family.
30
+ *
31
+ * @param value - The number to format.
32
+ * @param locale - BCP 47 locale tag. Defaults to the runtime locale.
33
+ * @returns A compact string representation of the number.
34
+ * @example
35
+ * formatCompact(1_500_000); // '1.5M' (en-US locale)
36
+ * formatCompact(1_000); // '1K'
37
+ * formatCompact(999); // '999'
38
+ * formatCompact(1_500_000, 'fr'); // '1,5 M'
39
+ * @since next
40
+ */
41
+ function formatCompact(value, locale) {
42
+ return new Intl.NumberFormat(locale, { notation: "compact" }).format(value);
43
+ }
44
+ //#endregion
45
+ //#region helpers/number/formatSize.ts
46
+ /**
47
+ * This file is part of helpers4.
48
+ * Copyright (C) 2025 baxyz
49
+ * SPDX-License-Identifier: LGPL-3.0-or-later
50
+ */
51
+ /** Size units in ascending order. */
52
+ var UNITS = [
53
+ "B",
54
+ "KB",
55
+ "MB",
56
+ "GB",
57
+ "TB"
58
+ ];
59
+ /**
60
+ * Format a byte count into a human-readable string with the appropriate unit.
61
+ *
62
+ * Each unit is 1024 of the previous (binary prefix). The result is formatted
63
+ * with one decimal place.
64
+ *
65
+ * @param bytes - A non-negative integer representing a byte count.
66
+ * @returns A human-readable string such as `'0.0B'`, `'1.5KB'`, `'3.2MB'`.
67
+ * @example
68
+ * formatSize(0) // '0.0B'
69
+ * formatSize(512) // '512.0B'
70
+ * formatSize(1024) // '1.0KB'
71
+ * formatSize(1536) // '1.5KB'
72
+ * formatSize(1_048_576) // '1.0MB'
73
+ * formatSize(1_073_741_824) // '1.0GB'
74
+ * @since next
75
+ */
76
+ function formatSize(bytes) {
77
+ let size = bytes;
78
+ let unitIndex = 0;
79
+ while (size >= 1024 && unitIndex < UNITS.length - 1) {
80
+ size /= 1024;
81
+ unitIndex++;
82
+ }
83
+ return `${size.toFixed(1)}${UNITS[unitIndex]}`;
84
+ }
85
+ //#endregion
86
+ //#region helpers/number/inRange.ts
87
+ /**
88
+ * Checks whether a number falls within `[min, max]` (both inclusive by default).
89
+ *
90
+ * @param value - The number to test
91
+ * @param min - Lower bound
92
+ * @param max - Upper bound
93
+ * @param options - Boundary inclusion mode (default: `'both'`)
94
+ * @returns `true` if `value` is within the specified range
95
+ * @example
96
+ * inRange(5, 1, 10) // => true
97
+ * inRange(1, 1, 10) // => true (min inclusive)
98
+ * inRange(1, 1, 10, { inclusive: 'none' }) // => false
99
+ * inRange(10, 1, 10, { inclusive: 'max' }) // => true
100
+ * @since next
101
+ */
102
+ function inRange(value, min, max, options = {}) {
103
+ const { inclusive = "both" } = options;
104
+ return (inclusive === "both" || inclusive === "min" ? value >= min : value > min) && (inclusive === "both" || inclusive === "max" ? value <= max : value < max);
105
+ }
106
+ //#endregion
107
+ //#region helpers/number/lerp.ts
108
+ /**
109
+ * This file is part of helpers4.
110
+ * Copyright (C) 2025 baxyz
111
+ * SPDX-License-Identifier: LGPL-3.0-or-later
112
+ */
113
+ /**
114
+ * Linearly interpolates between `start` and `end` by the factor `t`.
115
+ *
116
+ * - `t = 0` returns `start`.
117
+ * - `t = 1` returns `end`.
118
+ * - Values of `t` outside `[0, 1]` extrapolate beyond the range.
119
+ *
120
+ * @param start - The start value.
121
+ * @param end - The end value.
122
+ * @param t - The interpolation factor.
123
+ * @returns The interpolated value.
124
+ * @example
125
+ * lerp(0, 100, 0); // 0
126
+ * lerp(0, 100, 1); // 100
127
+ * lerp(0, 100, 0.5); // 50
128
+ * lerp(0, 100, 0.25); // 25
129
+ * @since next
130
+ */
131
+ function lerp(start, end, t) {
132
+ if (t === 0) return start;
133
+ if (t === 1) return end;
134
+ if (Object.is(start, end)) return start;
135
+ return start + (end - start) * t;
136
+ }
137
+ //#endregion
138
+ //#region helpers/number/mean.ts
139
+ /**
140
+ * This file is part of helpers4.
141
+ * Copyright (C) 2025 baxyz
142
+ * SPDX-License-Identifier: LGPL-3.0-or-later
143
+ */
144
+ /**
145
+ * Calculates the arithmetic mean (average) of an array of numbers.
146
+ * Returns `NaN` for an empty array.
147
+ *
148
+ * Pairs with {@link sum} for aggregate operations.
149
+ *
150
+ * @param array - The array of numbers to average
151
+ * @returns The arithmetic mean, or `NaN` if the array is empty
152
+ * @example
153
+ * mean([1, 2, 3, 4]) // => 2.5
154
+ * mean([10]) // => 10
155
+ * mean([]) // => NaN
156
+ * @since next
157
+ */
158
+ function mean(array) {
159
+ if (array.length === 0) return NaN;
160
+ return array.reduce((acc, n) => acc + n, 0) / array.length;
161
+ }
162
+ //#endregion
19
163
  //#region helpers/number/random.ts
20
164
  /**
21
165
  * This file is part of helpers4.
@@ -61,6 +205,25 @@ function roundTo(value, decimals) {
61
205
  return Math.round(value * multiplier) / multiplier;
62
206
  }
63
207
  //#endregion
64
- export { clamp, randomBetween, randomIntBetween, roundTo };
208
+ //#region helpers/number/sum.ts
209
+ /**
210
+ * This file is part of helpers4.
211
+ * Copyright (C) 2025 baxyz
212
+ * SPDX-License-Identifier: LGPL-3.0-or-later
213
+ */
214
+ /**
215
+ * Calculates the sum of an array of numbers.
216
+ * @param array - The array of numbers to sum
217
+ * @returns The sum of all values
218
+ * @example
219
+ * sum([1, 2, 3, 4])
220
+ * // => 10
221
+ * @since 2.0.0
222
+ */
223
+ function sum(array) {
224
+ return array.reduce((acc, n) => acc + n, 0);
225
+ }
226
+ //#endregion
227
+ export { clamp, formatCompact, formatSize, inRange, lerp, mean, randomBetween, randomIntBetween, roundTo, sum };
65
228
 
66
229
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../helpers/number/clamp.ts","../../../helpers/number/random.ts","../../../helpers/number/roundTo.ts"],"sourcesContent":["/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Clamps a number between min and max values\n * @param value - The value to clamp\n * @param min - Minimum value\n * @param max - Maximum value\n * @returns Clamped value\n * @since 1.9.0\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Generates a random number between min and max (inclusive)\n * @param min - Minimum value\n * @param max - Maximum value\n * @returns Random number between min and max\n * @since 1.9.0\n */\nexport function randomBetween(min: number, max: number): number {\n return Math.random() * (max - min) + min;\n}\n\n/**\n * Generates a random integer between min and max (inclusive)\n * @param min - Minimum value\n * @param max - Maximum value\n * @returns Random integer between min and max\n * @since 1.9.0\n */\nexport function randomIntBetween(min: number, max: number): number {\n return Math.floor(Math.random() * (max - min + 1)) + min;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Rounds a number to specified decimal places\n * @param value - The number to round\n * @param decimals - Number of decimal places\n * @returns Rounded number\n * @since 1.9.0\n */\nexport function roundTo(value: number, decimals: number): number {\n const multiplier = Math.pow(10, decimals);\n return Math.round(value * multiplier) / multiplier;\n}\n"],"mappings":";;;;;;;;;;;;;;AAcA,SAAgB,MAAM,OAAe,KAAa,KAAqB;AACrE,QAAO,KAAK,IAAI,KAAK,IAAI,OAAO,IAAI,EAAE,IAAI;;;;;;;;;;;;;;;;ACF5C,SAAgB,cAAc,KAAa,KAAqB;AAC9D,QAAO,KAAK,QAAQ,IAAI,MAAM,OAAO;;;;;;;;;AAUvC,SAAgB,iBAAiB,KAAa,KAAqB;AACjE,QAAO,KAAK,MAAM,KAAK,QAAQ,IAAI,MAAM,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;ACZvD,SAAgB,QAAQ,OAAe,UAA0B;CAC/D,MAAM,aAAa,KAAK,IAAI,IAAI,SAAS;AACzC,QAAO,KAAK,MAAM,QAAQ,WAAW,GAAG"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../helpers/number/clamp.ts","../../../helpers/number/formatCompact.ts","../../../helpers/number/formatSize.ts","../../../helpers/number/inRange.ts","../../../helpers/number/lerp.ts","../../../helpers/number/mean.ts","../../../helpers/number/random.ts","../../../helpers/number/roundTo.ts","../../../helpers/number/sum.ts"],"sourcesContent":["/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Clamps a number between min and max values\n * @param value - The value to clamp\n * @param min - Minimum value\n * @param max - Maximum value\n * @returns Clamped value\n * @since 1.9.0\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Formats a number using compact notation (e.g. `1_500_000 → \"1.5M\"`).\n *\n * Thin wrapper over `Intl.NumberFormat` with `notation: 'compact'`. Companion\n * of `formatSize` in the same `format*` family.\n *\n * @param value - The number to format.\n * @param locale - BCP 47 locale tag. Defaults to the runtime locale.\n * @returns A compact string representation of the number.\n * @example\n * formatCompact(1_500_000); // '1.5M' (en-US locale)\n * formatCompact(1_000); // '1K'\n * formatCompact(999); // '999'\n * formatCompact(1_500_000, 'fr'); // '1,5 M'\n * @since next\n */\nexport function formatCompact(value: number, locale?: string): string {\n return new Intl.NumberFormat(locale, { notation: 'compact' }).format(value);\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/** Size units in ascending order. */\nconst UNITS = ['B', 'KB', 'MB', 'GB', 'TB'] as const;\n\n/**\n * Format a byte count into a human-readable string with the appropriate unit.\n *\n * Each unit is 1024 of the previous (binary prefix). The result is formatted\n * with one decimal place.\n *\n * @param bytes - A non-negative integer representing a byte count.\n * @returns A human-readable string such as `'0.0B'`, `'1.5KB'`, `'3.2MB'`.\n * @example\n * formatSize(0) // '0.0B'\n * formatSize(512) // '512.0B'\n * formatSize(1024) // '1.0KB'\n * formatSize(1536) // '1.5KB'\n * formatSize(1_048_576) // '1.0MB'\n * formatSize(1_073_741_824) // '1.0GB'\n * @since next\n */\nexport function formatSize(bytes: number): string {\n let size = bytes;\n let unitIndex = 0;\n\n while (size >= 1024 && unitIndex < UNITS.length - 1) {\n size /= 1024;\n unitIndex++;\n }\n\n return `${size.toFixed(1)}${UNITS[unitIndex]}`;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Options for {@link inRange}.\n */\nexport interface InRangeOptions {\n /**\n * Which boundary (or boundaries) are included in the range.\n * - `'both'` (default): `min <= value <= max`\n * - `'min'`: `min <= value < max`\n * - `'max'`: `min < value <= max`\n * - `'none'`: `min < value < max`\n */\n inclusive?: 'both' | 'min' | 'max' | 'none';\n}\n\n/**\n * Checks whether a number falls within `[min, max]` (both inclusive by default).\n *\n * @param value - The number to test\n * @param min - Lower bound\n * @param max - Upper bound\n * @param options - Boundary inclusion mode (default: `'both'`)\n * @returns `true` if `value` is within the specified range\n * @example\n * inRange(5, 1, 10) // => true\n * inRange(1, 1, 10) // => true (min inclusive)\n * inRange(1, 1, 10, { inclusive: 'none' }) // => false\n * inRange(10, 1, 10, { inclusive: 'max' }) // => true\n * @since next\n */\nexport function inRange(value: number, min: number, max: number, options: InRangeOptions = {}): boolean {\n const { inclusive = 'both' } = options;\n const minOk = inclusive === 'both' || inclusive === 'min' ? value >= min : value > min;\n const maxOk = inclusive === 'both' || inclusive === 'max' ? value <= max : value < max;\n return minOk && maxOk;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Linearly interpolates between `start` and `end` by the factor `t`.\n *\n * - `t = 0` returns `start`.\n * - `t = 1` returns `end`.\n * - Values of `t` outside `[0, 1]` extrapolate beyond the range.\n *\n * @param start - The start value.\n * @param end - The end value.\n * @param t - The interpolation factor.\n * @returns The interpolated value.\n * @example\n * lerp(0, 100, 0); // 0\n * lerp(0, 100, 1); // 100\n * lerp(0, 100, 0.5); // 50\n * lerp(0, 100, 0.25); // 25\n * @since next\n */\nexport function lerp(start: number, end: number, t: number): number {\n if (t === 0) return start;\n if (t === 1) return end;\n if (Object.is(start, end)) return start;\n return start + (end - start) * t;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Calculates the arithmetic mean (average) of an array of numbers.\n * Returns `NaN` for an empty array.\n *\n * Pairs with {@link sum} for aggregate operations.\n *\n * @param array - The array of numbers to average\n * @returns The arithmetic mean, or `NaN` if the array is empty\n * @example\n * mean([1, 2, 3, 4]) // => 2.5\n * mean([10]) // => 10\n * mean([]) // => NaN\n * @since next\n */\nexport function mean(array: readonly number[]): number {\n if (array.length === 0) return NaN;\n return array.reduce((acc, n) => acc + n, 0) / array.length;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Generates a random number between min and max (inclusive)\n * @param min - Minimum value\n * @param max - Maximum value\n * @returns Random number between min and max\n * @since 1.9.0\n */\nexport function randomBetween(min: number, max: number): number {\n return Math.random() * (max - min) + min;\n}\n\n/**\n * Generates a random integer between min and max (inclusive)\n * @param min - Minimum value\n * @param max - Maximum value\n * @returns Random integer between min and max\n * @since 1.9.0\n */\nexport function randomIntBetween(min: number, max: number): number {\n return Math.floor(Math.random() * (max - min + 1)) + min;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Rounds a number to specified decimal places\n * @param value - The number to round\n * @param decimals - Number of decimal places\n * @returns Rounded number\n * @since 1.9.0\n */\nexport function roundTo(value: number, decimals: number): number {\n const multiplier = Math.pow(10, decimals);\n return Math.round(value * multiplier) / multiplier;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Calculates the sum of an array of numbers.\n * @param array - The array of numbers to sum\n * @returns The sum of all values\n * @example\n * sum([1, 2, 3, 4])\n * // => 10\n * @since 2.0.0\n */\nexport function sum(array: readonly number[]): number {\n return array.reduce((acc, n) => acc + n, 0);\n}\n"],"mappings":";;;;;;;;;;;;;;AAcA,SAAgB,MAAM,OAAe,KAAa,KAAqB;CACrE,OAAO,KAAK,IAAI,KAAK,IAAI,OAAO,IAAI,EAAE,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;ACO5C,SAAgB,cAAc,OAAe,QAAyB;CACpE,OAAO,IAAI,KAAK,aAAa,QAAQ,EAAE,UAAU,WAAW,CAAC,CAAC,OAAO,MAAM;;;;;;;;;;AChB7E,IAAM,QAAQ;CAAC;CAAK;CAAM;CAAM;CAAM;CAAK;;;;;;;;;;;;;;;;;;AAmB3C,SAAgB,WAAW,OAAuB;CAChD,IAAI,OAAO;CACX,IAAI,YAAY;CAEhB,OAAO,QAAQ,QAAQ,YAAY,MAAM,SAAS,GAAG;EACnD,QAAQ;EACR;;CAGF,OAAO,GAAG,KAAK,QAAQ,EAAE,GAAG,MAAM;;;;;;;;;;;;;;;;;;;ACApC,SAAgB,QAAQ,OAAe,KAAa,KAAa,UAA0B,EAAE,EAAW;CACtG,MAAM,EAAE,YAAY,WAAW;CAG/B,QAFc,cAAc,UAAU,cAAc,QAAQ,SAAS,MAAM,QAAQ,SACrE,cAAc,UAAU,cAAc,QAAQ,SAAS,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;ACdrF,SAAgB,KAAK,OAAe,KAAa,GAAmB;CAClE,IAAI,MAAM,GAAG,OAAO;CACpB,IAAI,MAAM,GAAG,OAAO;CACpB,IAAI,OAAO,GAAG,OAAO,IAAI,EAAE,OAAO;CAClC,OAAO,SAAS,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;ACRjC,SAAgB,KAAK,OAAkC;CACrD,IAAI,MAAM,WAAW,GAAG,OAAO;CAC/B,OAAO,MAAM,QAAQ,KAAK,MAAM,MAAM,GAAG,EAAE,GAAG,MAAM;;;;;;;;;;;;;;;;ACTtD,SAAgB,cAAc,KAAa,KAAqB;CAC9D,OAAO,KAAK,QAAQ,IAAI,MAAM,OAAO;;;;;;;;;AAUvC,SAAgB,iBAAiB,KAAa,KAAqB;CACjE,OAAO,KAAK,MAAM,KAAK,QAAQ,IAAI,MAAM,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;ACZvD,SAAgB,QAAQ,OAAe,UAA0B;CAC/D,MAAM,aAAa,KAAK,IAAI,IAAI,SAAS;CACzC,OAAO,KAAK,MAAM,QAAQ,WAAW,GAAG;;;;;;;;;;;;;;;;;;ACA1C,SAAgB,IAAI,OAAkC;CACpD,OAAO,MAAM,QAAQ,KAAK,MAAM,MAAM,GAAG,EAAE"}
package/llms.txt ADDED
@@ -0,0 +1,404 @@
1
+ # @helpers4/number
2
+
3
+ > Tree-shakable TypeScript utility functions for the `number` domain.
4
+ > Package: `@helpers4/number` — Version: 2.0.0-beta.3
5
+ > License: LGPL-3.0-or-later
6
+
7
+ ## Installation
8
+
9
+ ```sh
10
+ npm install @helpers4/number
11
+ # or
12
+ pnpm add @helpers4/number
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ```typescript
18
+ import { clamp, formatCompact, formatSize, ... } from '@helpers4/number';
19
+ ```
20
+
21
+ ## Functions
22
+
23
+ | Function | Description |
24
+ |---|---|
25
+ | `clamp` | Clamps a number between min and max values |
26
+ | `formatCompact` | Formats a number using compact notation (e.g. `1_500_000 → "1.5M"`). Thin wrapper over `Intl.Number |
27
+ | `formatSize` | Format a byte count into a human-readable string with the appropriate unit. Each unit is 1024 of th |
28
+ | `inRange` | Checks whether a number falls within `[min, max]` (both inclusive by default). |
29
+ | `lerp` | Linearly interpolates between `start` and `end` by the factor `t`. - `t = 0` returns `start`. - `t |
30
+ | `mean` | Calculates the arithmetic mean (average) of an array of numbers. Returns `NaN` for an empty array. |
31
+ | `randomBetween` | Generates a random number between min and max (inclusive) |
32
+ | `randomIntBetween` | Generates a random integer between min and max (inclusive) |
33
+ | `roundTo` | Rounds a number to specified decimal places |
34
+ | `sum` | Calculates the sum of an array of numbers. |
35
+
36
+ ---
37
+
38
+ ## API Reference
39
+
40
+ ### `clamp`
41
+
42
+ Clamps a number between min and max values
43
+
44
+ ```typescript
45
+ import { clamp } from '@helpers4/number';
46
+
47
+ clamp(value: number, min: number, max: number): number
48
+ ```
49
+
50
+ **Parameters:**
51
+
52
+ - `value: number` — The value to clamp
53
+ - `min: number` — Minimum value
54
+ - `max: number` — Maximum value
55
+
56
+ **Returns:** `number` — Clamped value
57
+
58
+ **Examples:**
59
+
60
+ *Clamp a value within range*
61
+
62
+ Restricts a number to be within a min/max range.
63
+
64
+ ```typescript
65
+ clamp(15, 0, 10) // => 10
66
+ clamp(-5, 0, 10) // => 0
67
+ clamp(5, 0, 10) // => 5
68
+ ```
69
+
70
+ ---
71
+
72
+ ### `formatCompact`
73
+
74
+ Formats a number using compact notation (e.g. `1_500_000 → "1.5M"`).
75
+
76
+ Thin wrapper over `Intl.NumberFormat` with `notation: 'compact'`. Companion
77
+ of `formatSize` in the same `format*` family.
78
+
79
+ ```typescript
80
+ import { formatCompact } from '@helpers4/number';
81
+
82
+ formatCompact(value: number, locale?: string): string
83
+ ```
84
+
85
+ **Parameters:**
86
+
87
+ - `value: number` — The number to format.
88
+ - `locale?: string` — BCP 47 locale tag. Defaults to the runtime locale.
89
+
90
+ **Returns:** `string` — A compact string representation of the number.
91
+
92
+ **Examples:**
93
+
94
+ *Compact large numbers*
95
+
96
+ Formats a number using K / M suffixes for readability.
97
+
98
+ ```typescript
99
+ formatCompact(1_500_000, 'en') // => '1.5M'
100
+ formatCompact(1_000, 'en') // => '1K'
101
+ formatCompact(999, 'en') // => '999'
102
+ ```
103
+
104
+ *Locale-aware formatting*
105
+
106
+ Uses the provided locale for the decimal separator and suffix.
107
+
108
+ ```typescript
109
+ formatCompact(1_500_000, 'fr') // => '1,5 M'
110
+ ```
111
+
112
+ ---
113
+
114
+ ### `formatSize`
115
+
116
+ Format a byte count into a human-readable string with the appropriate unit.
117
+
118
+ Each unit is 1024 of the previous (binary prefix). The result is formatted
119
+ with one decimal place.
120
+
121
+ ```typescript
122
+ import { formatSize } from '@helpers4/number';
123
+
124
+ formatSize(bytes: number): string
125
+ ```
126
+
127
+ **Parameters:**
128
+
129
+ - `bytes: number` — A non-negative integer representing a byte count.
130
+
131
+ **Returns:** `string` — A human-readable string such as `'0.0B'`, `'1.5KB'`, `'3.2MB'`.
132
+
133
+ **Examples:**
134
+
135
+ *Format bytes to human-readable size*
136
+
137
+ Converts a raw byte count to a human-readable string using binary prefixes.
138
+
139
+ ```typescript
140
+ formatSize(0) // '0.0B'
141
+ formatSize(512) // '512.0B'
142
+ formatSize(1024) // '1.0KB'
143
+ formatSize(1_048_576) // '1.0MB'
144
+ formatSize(1_073_741_824) // '1.0GB'
145
+ ```
146
+
147
+ ---
148
+
149
+ ### `inRange`
150
+
151
+ Checks whether a number falls within `[min, max]` (both inclusive by default).
152
+
153
+ ```typescript
154
+ import { inRange } from '@helpers4/number';
155
+
156
+ inRange(value: number, min: number, max: number, options: InRangeOptions): boolean
157
+ ```
158
+
159
+ **Parameters:**
160
+
161
+ - `value: number` — The number to test
162
+ - `min: number` — Lower bound
163
+ - `max: number` — Upper bound
164
+ - `options: InRangeOptions` (default: `{}`) — Boundary inclusion mode (default: `'both'`)
165
+
166
+ **Returns:** `boolean` — `true` if `value` is within the specified range
167
+
168
+ **Examples:**
169
+
170
+ *Check if a value is within bounds (inclusive)*
171
+
172
+ Both min and max are included by default.
173
+
174
+ ```typescript
175
+ inRange(5, 1, 10) // => true
176
+ inRange(0, 1, 10) // => false
177
+ inRange(1, 1, 10) // => true (min included)
178
+ inRange(10, 1, 10) // => true (max included)
179
+ ```
180
+
181
+ *Exclusive range*
182
+
183
+ Use { inclusive: "none" } for open interval (min, max).
184
+
185
+ ```typescript
186
+ inRange(5, 1, 10, { inclusive: 'none' }) // => true
187
+ inRange(1, 1, 10, { inclusive: 'none' }) // => false
188
+ inRange(10, 1, 10, { inclusive: 'none' }) // => false
189
+ ```
190
+
191
+ ---
192
+
193
+ ### `lerp`
194
+
195
+ Linearly interpolates between `start` and `end` by the factor `t`.
196
+
197
+ - `t = 0` returns `start`.
198
+ - `t = 1` returns `end`.
199
+ - Values of `t` outside `[0, 1]` extrapolate beyond the range.
200
+
201
+ ```typescript
202
+ import { lerp } from '@helpers4/number';
203
+
204
+ lerp(start: number, end: number, t: number): number
205
+ ```
206
+
207
+ **Parameters:**
208
+
209
+ - `start: number` — The start value.
210
+ - `end: number` — The end value.
211
+ - `t: number` — The interpolation factor.
212
+
213
+ **Returns:** `number` — The interpolated value.
214
+
215
+ **Examples:**
216
+
217
+ *Interpolate between two values*
218
+
219
+ Returns the value between start and end at position t (0 = start, 1 = end).
220
+
221
+ ```typescript
222
+ lerp(0, 100, 0) // => 0
223
+ lerp(0, 100, 0.5) // => 50
224
+ lerp(0, 100, 1) // => 100
225
+ ```
226
+
227
+ *Animate a colour channel*
228
+
229
+ t outside [0, 1] extrapolates beyond the range.
230
+
231
+ ```typescript
232
+ lerp(0, 255, 0.5) // => 127.5
233
+ lerp(0, 10, 2) // => 20 (extrapolation)
234
+ ```
235
+
236
+ ---
237
+
238
+ ### `mean`
239
+
240
+ Calculates the arithmetic mean (average) of an array of numbers.
241
+ Returns `NaN` for an empty array.
242
+
243
+ Pairs with sum for aggregate operations.
244
+
245
+ ```typescript
246
+ import { mean } from '@helpers4/number';
247
+
248
+ mean(array: readonly number[]): number
249
+ ```
250
+
251
+ **Parameters:**
252
+
253
+ - `array: readonly number[]` — The array of numbers to average
254
+
255
+ **Returns:** `number` — The arithmetic mean, or `NaN` if the array is empty
256
+
257
+ **Examples:**
258
+
259
+ *Average a list of numbers*
260
+
261
+ Returns the arithmetic mean of the array; NaN for empty arrays.
262
+
263
+ ```typescript
264
+ mean([1, 2, 3, 4]) // => 2.5
265
+ mean([10, 20, 30]) // => 20
266
+ mean([]) // => NaN
267
+ ```
268
+
269
+ ---
270
+
271
+ ### `randomBetween`
272
+
273
+ Generates a random number between min and max (inclusive)
274
+
275
+ ```typescript
276
+ import { randomBetween } from '@helpers4/number';
277
+
278
+ randomBetween(min: number, max: number): number
279
+ ```
280
+
281
+ **Parameters:**
282
+
283
+ - `min: number` — Minimum value
284
+ - `max: number` — Maximum value
285
+
286
+ **Returns:** `number` — Random number between min and max
287
+
288
+ **Examples:**
289
+
290
+ *Generate a random float in range*
291
+
292
+ Returns a random number between min and max (inclusive).
293
+
294
+ ```typescript
295
+ randomBetween(1, 10)
296
+ // => e.g. 5.327...
297
+ ```
298
+
299
+ *Generate a random integer in range*
300
+
301
+ Returns a random integer between min and max (inclusive).
302
+
303
+ ```typescript
304
+ randomIntBetween(1, 6)
305
+ // => e.g. 4
306
+ ```
307
+
308
+ ---
309
+
310
+ ### `randomIntBetween`
311
+
312
+ Generates a random integer between min and max (inclusive)
313
+
314
+ ```typescript
315
+ import { randomIntBetween } from '@helpers4/number';
316
+
317
+ randomIntBetween(min: number, max: number): number
318
+ ```
319
+
320
+ **Parameters:**
321
+
322
+ - `min: number` — Minimum value
323
+ - `max: number` — Maximum value
324
+
325
+ **Returns:** `number` — Random integer between min and max
326
+
327
+ ---
328
+
329
+ ### `roundTo`
330
+
331
+ Rounds a number to specified decimal places
332
+
333
+ ```typescript
334
+ import { roundTo } from '@helpers4/number';
335
+
336
+ roundTo(value: number, decimals: number): number
337
+ ```
338
+
339
+ **Parameters:**
340
+
341
+ - `value: number` — The number to round
342
+ - `decimals: number` — Number of decimal places
343
+
344
+ **Returns:** `number` — Rounded number
345
+
346
+ **Examples:**
347
+
348
+ *Round to 2 decimal places*
349
+
350
+ Rounds a floating-point number to the specified number of decimals.
351
+
352
+ ```typescript
353
+ roundTo(3.14159, 2)
354
+ // => 3.14
355
+ ```
356
+
357
+ *Round to 0 decimal places*
358
+
359
+ Effectively rounds to the nearest integer.
360
+
361
+ ```typescript
362
+ roundTo(3.7, 0)
363
+ // => 4
364
+ ```
365
+
366
+ ---
367
+
368
+ ### `sum`
369
+
370
+ Calculates the sum of an array of numbers.
371
+
372
+ ```typescript
373
+ import { sum } from '@helpers4/number';
374
+
375
+ sum(array: readonly number[]): number
376
+ ```
377
+
378
+ **Parameters:**
379
+
380
+ - `array: readonly number[]` — The array of numbers to sum
381
+
382
+ **Returns:** `number` — The sum of all values
383
+
384
+ **Examples:**
385
+
386
+ *Sum numbers*
387
+
388
+ Calculates the sum of an array of numbers.
389
+
390
+ ```typescript
391
+ sum([1, 2, 3, 4])
392
+ // => 10
393
+ ```
394
+
395
+ *Sum with negative numbers*
396
+
397
+ Handles negative numbers correctly.
398
+
399
+ ```typescript
400
+ sum([10, -3, 5, -2])
401
+ // => 10
402
+ ```
403
+
404
+ ---
package/meta/api.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "category": "number",
3
- "version": "2.0.0-alpha.9",
3
+ "version": "2.0.0-beta.3",
4
4
  "functions": [
5
5
  {
6
6
  "name": "clamp",
@@ -43,6 +43,215 @@
43
43
  ],
44
44
  "sourceFile": "clamp.ts"
45
45
  },
46
+ {
47
+ "name": "formatCompact",
48
+ "kind": "function",
49
+ "description": "Formats a number using compact notation (e.g. `1_500_000 → \"1.5M\"`).\n\nThin wrapper over `Intl.NumberFormat` with `notation: 'compact'`. Companion\nof `formatSize` in the same `format*` family.",
50
+ "since": "next",
51
+ "signatures": [
52
+ {
53
+ "signature": "formatCompact(value: number, locale?: string): string",
54
+ "description": "Formats a number using compact notation (e.g. `1_500_000 → \"1.5M\"`).\n\nThin wrapper over `Intl.NumberFormat` with `notation: 'compact'`. Companion\nof `formatSize` in the same `format*` family.",
55
+ "params": [
56
+ {
57
+ "name": "value",
58
+ "type": "number",
59
+ "description": "The number to format."
60
+ },
61
+ {
62
+ "name": "locale",
63
+ "type": "string",
64
+ "description": "BCP 47 locale tag. Defaults to the runtime locale.",
65
+ "optional": true
66
+ }
67
+ ],
68
+ "returns": {
69
+ "type": "string",
70
+ "description": "A compact string representation of the number."
71
+ }
72
+ }
73
+ ],
74
+ "examples": [
75
+ {
76
+ "title": "Compact large numbers",
77
+ "description": "Formats a number using K / M suffixes for readability.",
78
+ "code": "formatCompact(1_500_000, 'en') // => '1.5M'\nformatCompact(1_000, 'en') // => '1K'\nformatCompact(999, 'en') // => '999'"
79
+ },
80
+ {
81
+ "title": "Locale-aware formatting",
82
+ "description": "Uses the provided locale for the decimal separator and suffix.",
83
+ "code": "formatCompact(1_500_000, 'fr') // => '1,5 M'"
84
+ }
85
+ ],
86
+ "sourceFile": "formatCompact.ts"
87
+ },
88
+ {
89
+ "name": "formatSize",
90
+ "kind": "function",
91
+ "description": "Format a byte count into a human-readable string with the appropriate unit.\n\nEach unit is 1024 of the previous (binary prefix). The result is formatted\nwith one decimal place.",
92
+ "since": "next",
93
+ "signatures": [
94
+ {
95
+ "signature": "formatSize(bytes: number): string",
96
+ "description": "Format a byte count into a human-readable string with the appropriate unit.\n\nEach unit is 1024 of the previous (binary prefix). The result is formatted\nwith one decimal place.",
97
+ "params": [
98
+ {
99
+ "name": "bytes",
100
+ "type": "number",
101
+ "description": "A non-negative integer representing a byte count."
102
+ }
103
+ ],
104
+ "returns": {
105
+ "type": "string",
106
+ "description": "A human-readable string such as `'0.0B'`, `'1.5KB'`, `'3.2MB'`."
107
+ }
108
+ }
109
+ ],
110
+ "examples": [
111
+ {
112
+ "title": "Format bytes to human-readable size",
113
+ "description": "Converts a raw byte count to a human-readable string using binary prefixes.",
114
+ "code": "formatSize(0) // '0.0B'\nformatSize(512) // '512.0B'\nformatSize(1024) // '1.0KB'\nformatSize(1_048_576) // '1.0MB'\nformatSize(1_073_741_824) // '1.0GB'"
115
+ }
116
+ ],
117
+ "sourceFile": "formatSize.ts"
118
+ },
119
+ {
120
+ "name": "inRange",
121
+ "kind": "function",
122
+ "description": "Checks whether a number falls within `[min, max]` (both inclusive by default).",
123
+ "since": "next",
124
+ "signatures": [
125
+ {
126
+ "signature": "inRange(value: number, min: number, max: number, options: InRangeOptions): boolean",
127
+ "description": "Checks whether a number falls within `[min, max]` (both inclusive by default).",
128
+ "params": [
129
+ {
130
+ "name": "value",
131
+ "type": "number",
132
+ "description": "The number to test"
133
+ },
134
+ {
135
+ "name": "min",
136
+ "type": "number",
137
+ "description": "Lower bound"
138
+ },
139
+ {
140
+ "name": "max",
141
+ "type": "number",
142
+ "description": "Upper bound"
143
+ },
144
+ {
145
+ "name": "options",
146
+ "type": "InRangeOptions",
147
+ "description": "Boundary inclusion mode (default: `'both'`)",
148
+ "defaultValue": "{}"
149
+ }
150
+ ],
151
+ "returns": {
152
+ "type": "boolean",
153
+ "description": "`true` if `value` is within the specified range"
154
+ }
155
+ }
156
+ ],
157
+ "examples": [
158
+ {
159
+ "title": "Check if a value is within bounds (inclusive)",
160
+ "description": "Both min and max are included by default.",
161
+ "code": "inRange(5, 1, 10) // => true\ninRange(0, 1, 10) // => false\ninRange(1, 1, 10) // => true (min included)\ninRange(10, 1, 10) // => true (max included)"
162
+ },
163
+ {
164
+ "title": "Exclusive range",
165
+ "description": "Use { inclusive: \"none\" } for open interval (min, max).",
166
+ "code": "inRange(5, 1, 10, { inclusive: 'none' }) // => true\ninRange(1, 1, 10, { inclusive: 'none' }) // => false\ninRange(10, 1, 10, { inclusive: 'none' }) // => false"
167
+ }
168
+ ],
169
+ "sourceFile": "inRange.ts",
170
+ "relatedTypes": [
171
+ {
172
+ "name": "InRangeOptions",
173
+ "description": "Options for inRange.",
174
+ "typeDefinition": "interface InRangeOptions {\n inclusive?: \"min\" | \"max\" | \"both\" | \"none\";\n}"
175
+ }
176
+ ]
177
+ },
178
+ {
179
+ "name": "lerp",
180
+ "kind": "function",
181
+ "description": "Linearly interpolates between `start` and `end` by the factor `t`.\n\n- `t = 0` returns `start`.\n- `t = 1` returns `end`.\n- Values of `t` outside `[0, 1]` extrapolate beyond the range.",
182
+ "since": "next",
183
+ "signatures": [
184
+ {
185
+ "signature": "lerp(start: number, end: number, t: number): number",
186
+ "description": "Linearly interpolates between `start` and `end` by the factor `t`.\n\n- `t = 0` returns `start`.\n- `t = 1` returns `end`.\n- Values of `t` outside `[0, 1]` extrapolate beyond the range.",
187
+ "params": [
188
+ {
189
+ "name": "start",
190
+ "type": "number",
191
+ "description": "The start value."
192
+ },
193
+ {
194
+ "name": "end",
195
+ "type": "number",
196
+ "description": "The end value."
197
+ },
198
+ {
199
+ "name": "t",
200
+ "type": "number",
201
+ "description": "The interpolation factor."
202
+ }
203
+ ],
204
+ "returns": {
205
+ "type": "number",
206
+ "description": "The interpolated value."
207
+ }
208
+ }
209
+ ],
210
+ "examples": [
211
+ {
212
+ "title": "Interpolate between two values",
213
+ "description": "Returns the value between start and end at position t (0 = start, 1 = end).",
214
+ "code": "lerp(0, 100, 0) // => 0\nlerp(0, 100, 0.5) // => 50\nlerp(0, 100, 1) // => 100"
215
+ },
216
+ {
217
+ "title": "Animate a colour channel",
218
+ "description": "t outside [0, 1] extrapolates beyond the range.",
219
+ "code": "lerp(0, 255, 0.5) // => 127.5\nlerp(0, 10, 2) // => 20 (extrapolation)"
220
+ }
221
+ ],
222
+ "sourceFile": "lerp.ts"
223
+ },
224
+ {
225
+ "name": "mean",
226
+ "kind": "function",
227
+ "description": "Calculates the arithmetic mean (average) of an array of numbers.\nReturns `NaN` for an empty array.\n\nPairs with sum for aggregate operations.",
228
+ "since": "next",
229
+ "signatures": [
230
+ {
231
+ "signature": "mean(array: readonly number[]): number",
232
+ "description": "Calculates the arithmetic mean (average) of an array of numbers.\nReturns `NaN` for an empty array.\n\nPairs with sum for aggregate operations.",
233
+ "params": [
234
+ {
235
+ "name": "array",
236
+ "type": "readonly number[]",
237
+ "description": "The array of numbers to average"
238
+ }
239
+ ],
240
+ "returns": {
241
+ "type": "number",
242
+ "description": "The arithmetic mean, or `NaN` if the array is empty"
243
+ }
244
+ }
245
+ ],
246
+ "examples": [
247
+ {
248
+ "title": "Average a list of numbers",
249
+ "description": "Returns the arithmetic mean of the array; NaN for empty arrays.",
250
+ "code": "mean([1, 2, 3, 4]) // => 2.5\nmean([10, 20, 30]) // => 20\nmean([]) // => NaN"
251
+ }
252
+ ],
253
+ "sourceFile": "mean.ts"
254
+ },
46
255
  {
47
256
  "name": "randomBetween",
48
257
  "kind": "function",
@@ -154,6 +363,42 @@
154
363
  }
155
364
  ],
156
365
  "sourceFile": "roundTo.ts"
366
+ },
367
+ {
368
+ "name": "sum",
369
+ "kind": "function",
370
+ "description": "Calculates the sum of an array of numbers.",
371
+ "since": "2.0.0",
372
+ "signatures": [
373
+ {
374
+ "signature": "sum(array: readonly number[]): number",
375
+ "description": "Calculates the sum of an array of numbers.",
376
+ "params": [
377
+ {
378
+ "name": "array",
379
+ "type": "readonly number[]",
380
+ "description": "The array of numbers to sum"
381
+ }
382
+ ],
383
+ "returns": {
384
+ "type": "number",
385
+ "description": "The sum of all values"
386
+ }
387
+ }
388
+ ],
389
+ "examples": [
390
+ {
391
+ "title": "Sum numbers",
392
+ "description": "Calculates the sum of an array of numbers.",
393
+ "code": "sum([1, 2, 3, 4])\n// => 10"
394
+ },
395
+ {
396
+ "title": "Sum with negative numbers",
397
+ "description": "Handles negative numbers correctly.",
398
+ "code": "sum([10, -3, 5, -2])\n// => 10"
399
+ }
400
+ ],
401
+ "sourceFile": "sum.ts"
157
402
  }
158
403
  ]
159
404
  }
@@ -0,0 +1,6 @@
1
+ {
2
+ "category": "number",
3
+ "label": "Number",
4
+ "smallDescription": "Number utility functions and validation",
5
+ "description": "Utilities for working with numbers including clamping, parity checks, and numeric validation"
6
+ }
@@ -11,6 +11,71 @@
11
11
  }
12
12
  ]
13
13
  },
14
+ {
15
+ "name": "formatCompact",
16
+ "examples": [
17
+ {
18
+ "title": "Compact large numbers",
19
+ "description": "Formats a number using K / M suffixes for readability.",
20
+ "code": "formatCompact(1_500_000, 'en') // => '1.5M'\nformatCompact(1_000, 'en') // => '1K'\nformatCompact(999, 'en') // => '999'"
21
+ },
22
+ {
23
+ "title": "Locale-aware formatting",
24
+ "description": "Uses the provided locale for the decimal separator and suffix.",
25
+ "code": "formatCompact(1_500_000, 'fr') // => '1,5 M'"
26
+ }
27
+ ]
28
+ },
29
+ {
30
+ "name": "formatSize",
31
+ "examples": [
32
+ {
33
+ "title": "Format bytes to human-readable size",
34
+ "description": "Converts a raw byte count to a human-readable string using binary prefixes.",
35
+ "code": "formatSize(0) // '0.0B'\nformatSize(512) // '512.0B'\nformatSize(1024) // '1.0KB'\nformatSize(1_048_576) // '1.0MB'\nformatSize(1_073_741_824) // '1.0GB'"
36
+ }
37
+ ]
38
+ },
39
+ {
40
+ "name": "inRange",
41
+ "examples": [
42
+ {
43
+ "title": "Check if a value is within bounds (inclusive)",
44
+ "description": "Both min and max are included by default.",
45
+ "code": "inRange(5, 1, 10) // => true\ninRange(0, 1, 10) // => false\ninRange(1, 1, 10) // => true (min included)\ninRange(10, 1, 10) // => true (max included)"
46
+ },
47
+ {
48
+ "title": "Exclusive range",
49
+ "description": "Use { inclusive: \"none\" } for open interval (min, max).",
50
+ "code": "inRange(5, 1, 10, { inclusive: 'none' }) // => true\ninRange(1, 1, 10, { inclusive: 'none' }) // => false\ninRange(10, 1, 10, { inclusive: 'none' }) // => false"
51
+ }
52
+ ]
53
+ },
54
+ {
55
+ "name": "lerp",
56
+ "examples": [
57
+ {
58
+ "title": "Interpolate between two values",
59
+ "description": "Returns the value between start and end at position t (0 = start, 1 = end).",
60
+ "code": "lerp(0, 100, 0) // => 0\nlerp(0, 100, 0.5) // => 50\nlerp(0, 100, 1) // => 100"
61
+ },
62
+ {
63
+ "title": "Animate a colour channel",
64
+ "description": "t outside [0, 1] extrapolates beyond the range.",
65
+ "code": "lerp(0, 255, 0.5) // => 127.5\nlerp(0, 10, 2) // => 20 (extrapolation)"
66
+ }
67
+ ]
68
+ },
69
+ {
70
+ "name": "mean",
71
+ "examples": [
72
+ {
73
+ "title": "Average a list of numbers",
74
+ "description": "Returns the arithmetic mean of the array; NaN for empty arrays.",
75
+ "code": "mean([1, 2, 3, 4]) // => 2.5\nmean([10, 20, 30]) // => 20\nmean([]) // => NaN"
76
+ }
77
+ ]
78
+ },
14
79
  {
15
80
  "name": "randomBetween",
16
81
  "examples": [
@@ -40,6 +105,21 @@
40
105
  "code": "roundTo(3.7, 0)\n// => 4"
41
106
  }
42
107
  ]
108
+ },
109
+ {
110
+ "name": "sum",
111
+ "examples": [
112
+ {
113
+ "title": "Sum numbers",
114
+ "description": "Calculates the sum of an array of numbers.",
115
+ "code": "sum([1, 2, 3, 4])\n// => 10"
116
+ },
117
+ {
118
+ "title": "Sum with negative numbers",
119
+ "description": "Handles negative numbers correctly.",
120
+ "code": "sum([10, -3, 5, -2])\n// => 10"
121
+ }
122
+ ]
43
123
  }
44
124
  ]
45
125
  }
@@ -0,0 +1,37 @@
1
+ {
2
+ "category": "number",
3
+ "functions": [
4
+ {
5
+ "name": "min / max",
6
+ "libraries": [
7
+ "lodash",
8
+ "radashi",
9
+ "ramda"
10
+ ],
11
+ "native": "Math.min(...arr) / Math.max(...arr)",
12
+ "since": "ES1",
13
+ "example": "Math.min(...numbers)\nMath.max(...numbers)",
14
+ "notes": "For large arrays, prefer reduce to avoid stack overflow"
15
+ },
16
+ {
17
+ "name": "ceil / floor",
18
+ "libraries": [
19
+ "lodash"
20
+ ],
21
+ "native": "Math.ceil() / Math.floor()",
22
+ "since": "ES1",
23
+ "example": "Math.ceil(4.2) // 5\nMath.floor(4.8) // 4",
24
+ "notes": "No precision param natively; use roundTo from helpers4 for decimal precision"
25
+ },
26
+ {
27
+ "name": "toInt / toFloat",
28
+ "libraries": [
29
+ "radashi"
30
+ ],
31
+ "native": "parseInt(str, 10) / parseFloat(str)",
32
+ "since": "ES1",
33
+ "example": "parseInt('42px', 10) // 42\nparseFloat('3.14') // 3.14",
34
+ "notes": "Radashi adds default-value fallback on NaN"
35
+ }
36
+ ]
37
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@helpers4/number",
3
- "version": "2.0.0-alpha.9",
3
+ "version": "2.0.0-beta.3",
4
4
  "description": "A set of helpers in TS/JS, compatible with tree-shaking, for number.",
5
5
  "author": "baxyz <baxy@etik.com>",
6
6
  "license": "LGPL-3.0",
@@ -21,20 +21,28 @@
21
21
  "./meta/api.json": "./meta/api.json",
22
22
  "./meta/examples.json": "./meta/examples.json",
23
23
  "./meta/licenses.json": "./meta/licenses.json",
24
+ "./llms.txt": "./llms.txt",
24
25
  "./package.json": "./package.json"
25
26
  },
26
27
  "keywords": [
27
28
  "helpers",
28
29
  "number",
29
30
  "clamp",
31
+ "formatCompact",
32
+ "formatSize",
33
+ "inRange",
34
+ "lerp",
35
+ "mean",
30
36
  "random",
31
- "roundTo"
37
+ "roundTo",
38
+ "sum"
32
39
  ],
33
40
  "files": [
34
41
  "lib/index.js",
35
42
  "lib/index.d.ts",
36
43
  "lib/index.js.map",
37
44
  "meta/",
45
+ "llms.txt",
38
46
  "LICENSE.md",
39
47
  "package.json",
40
48
  "README.md"