@react-hive/honey-utils 1.6.0 โ†’ 1.8.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.
package/README.md CHANGED
@@ -11,8 +11,6 @@ A lightweight TypeScript utility library providing a collection of helper functi
11
11
 
12
12
  ## Features
13
13
 
14
- ---
15
-
16
14
  - ๐Ÿ” **Type Guards** - Functions for runtime type checking
17
15
  - ๐Ÿงต **String Utilities** - String manipulation and transformation
18
16
  - ๐Ÿ”ข **Array Utilities** - Array filtering and manipulation
@@ -24,8 +22,6 @@ A lightweight TypeScript utility library providing a collection of helper functi
24
22
 
25
23
  ## Installation
26
24
 
27
- ---
28
-
29
25
  ```bash
30
26
  # Using npm
31
27
  npm install @react-hive/honey-utils
@@ -39,8 +35,6 @@ pnpm add @react-hive/honey-utils
39
35
 
40
36
  ## Usage
41
37
 
42
- ---
43
-
44
38
  ### Importing
45
39
 
46
40
  ```ts
@@ -56,16 +50,24 @@ import * as HoneyUtils from '@react-hive/honey-utils';
56
50
  ```ts
57
51
  import { toKebabCase, camelToDashCase, splitStringIntoWords, hashString } from '@react-hive/honey-utils';
58
52
 
59
- // Convert string to kebab-case
53
+ /**
54
+ * Convert string to kebab-case
55
+ */
60
56
  toKebabCase('helloWorld'); // 'hello-world'
61
57
 
62
- // Convert camelCase to dash-case
58
+ /**
59
+ * Convert camelCase to dash-case
60
+ */
63
61
  camelToDashCase('helloWorld'); // 'hello-world'
64
62
 
65
- // Split string into words
63
+ /**
64
+ * Split string into words
65
+ */
66
66
  splitStringIntoWords('hello world'); // ['hello', 'world']
67
67
 
68
- // Generate a hash from a string
68
+ /**
69
+ * Generate a hash from a string
70
+ */
69
71
  const hash = hashString('background-color: red;'); // 'e4k1z0x'
70
72
  ```
71
73
 
@@ -73,95 +75,129 @@ const hash = hashString('background-color: red;'); // 'e4k1z0x'
73
75
 
74
76
  ```ts
75
77
  import {
76
- boolFilter,
77
- unique,
78
- chunk,
79
- intersection,
80
- difference,
81
- mapAsync,
82
- forAsync,
83
- reduceAsync,
84
- filterAsync,
85
- someAsync,
86
- everyAsync,
87
- findAsync,
78
+ boolFilter,
79
+ unique,
80
+ chunk,
81
+ intersection,
82
+ difference,
83
+ runParallel,
84
+ runSequential,
85
+ reduceAsync,
86
+ filterAsync,
87
+ someAsync,
88
+ everyAsync,
89
+ findAsync,
90
+ pipe,
91
+ compose,
88
92
  } from '@react-hive/honey-utils';
89
93
 
90
- // Filter out falsy values from an array
91
- boolFilter([0, 1, false, 2, '', 3, null, undefined, true]);
94
+ /**
95
+ * Filter out falsy values from an array
96
+ */
97
+ boolFilter([0, 1, false, 2, '', 3, null, undefined, true]);
92
98
  // โžœ [1, 2, 3, true]
93
99
 
94
- // Remove duplicate values from an array
95
- unique([1, 2, 2, 3, 1, 4]);
100
+ /**
101
+ * Remove duplicate values from an array
102
+ */
103
+ unique([1, 2, 2, 3, 1, 4]);
96
104
  // โžœ [1, 2, 3, 4]
97
105
 
98
- // Split an array into chunks of specified size
99
- chunk([1, 2, 3, 4, 5], 2);
106
+ /**
107
+ * Split an array into chunks of specified size
108
+ */
109
+ chunk([1, 2, 3, 4, 5], 2);
100
110
  // โžœ [[1, 2], [3, 4], [5]]
101
111
 
102
- // Find common elements between arrays
103
- intersection([1, 2, 3], [2, 3, 4]);
112
+ /**
113
+ * Find common elements between arrays
114
+ */
115
+ intersection([1, 2, 3], [2, 3, 4]);
104
116
  // โžœ [2, 3]
105
117
 
106
- // Find elements in one array not in another
107
- difference([1, 2, 3, 4], [2, 4]);
118
+ /**
119
+ * Find elements in one array not in another
120
+ */
121
+ difference([1, 2, 3, 4], [2, 4]);
108
122
  // โžœ [1, 3]
109
123
 
110
- // Run async operations in parallel and collect results
111
- await mapAsync([1, 2, 3], async (n) => {
112
- await delay(100);
113
-
114
- return n * 2;
124
+ /**
125
+ * Run async operations in parallel and collect results
126
+ */
127
+ await runParallel([1, 2, 3], async (n) => {
128
+ await delay(100);
129
+ return n * 2;
115
130
  });
116
131
  // โžœ [2, 4, 6]
117
132
 
118
- // Run async operations sequentially and collect results
119
- await forAsync([1, 2, 3], async (n, i) => {
120
- await delay(100);
121
-
122
- return n * i;
133
+ /**
134
+ * Run async operations sequentially and collect results
135
+ */
136
+ await runSequential([1, 2, 3], async (n, i) => {
137
+ await delay(100);
138
+ return n * i;
123
139
  });
124
140
  // โžœ [0, 2, 6]
125
141
 
126
- // Reduce array asynchronously
142
+ /**
143
+ * Reduce array asynchronously
144
+ */
127
145
  await reduceAsync([1, 2, 3], async (acc, n) => {
128
- await delay(50);
129
-
130
- return acc + n;
146
+ await delay(50);
147
+ return acc + n;
131
148
  }, 0);
132
149
  // โžœ 6
133
150
 
134
- // Filter array asynchronously
151
+ /**
152
+ * Filter array asynchronously
153
+ */
135
154
  await filterAsync([1, 2, 3, 4], async (n) => {
136
- await delay(30);
137
-
138
- return n % 2 === 0;
155
+ await delay(30);
156
+ return n % 2 === 0;
139
157
  });
140
158
  // โžœ [2, 4]
141
159
 
142
- // Check if some items match condition asynchronously
160
+ /**
161
+ * Check if some items match condition asynchronously
162
+ */
143
163
  await someAsync([1, 3, 5], async (n) => {
144
- await delay(10);
145
-
146
- return n % 2 === 0;
164
+ await delay(10);
165
+ return n % 2 === 0;
147
166
  });
148
167
  // โžœ false
149
168
 
150
- // Check if all items match condition asynchronously
169
+ /**
170
+ * Check if all items match condition asynchronously
171
+ */
151
172
  await everyAsync([2, 4, 6], async (n) => {
152
- await delay(10);
153
-
154
- return n % 2 === 0;
173
+ await delay(10);
174
+ return n % 2 === 0;
155
175
  });
156
176
  // โžœ true
157
177
 
158
- // Find first matching item asynchronously
178
+ /**
179
+ * Find first matching item asynchronously
180
+ */
159
181
  await findAsync([1, 3, 4, 5], async (n) => {
160
- await delay(20);
161
-
162
- return n % 2 === 0;
182
+ await delay(20);
183
+ return n % 2 === 0;
163
184
  });
164
185
  // โžœ 4
186
+
187
+ /**
188
+ * Compose functions from left to right
189
+ */
190
+ const double = (n: number) => n * 2;
191
+ const increment = (n: number) => n + 1;
192
+
193
+ pipe(double, increment)(3);
194
+ // โžœ 7 โ†’ increment(double(3)) โ†’ increment(6)
195
+
196
+ /**
197
+ * Compose functions from right to left
198
+ */
199
+ compose(increment, double)(3);
200
+ // โžœ 7 โ†’ increment(double(3)) โ†’ increment(6)
165
201
  ```
166
202
 
167
203
  ### Function Utilities
@@ -169,19 +205,27 @@ await findAsync([1, 3, 4, 5], async (n) => {
169
205
  ```ts
170
206
  import { noop, invokeIfFunction, delay, retry } from '@react-hive/honey-utils';
171
207
 
172
- // No-operation function
173
- noop(); // does nothing
208
+ /**
209
+ * No-operation function. Does nothing
210
+ */
211
+ noop();
174
212
 
175
- // Invoke if function, otherwise return value
213
+ /**
214
+ * Invoke if function, otherwise return value
215
+ */
176
216
  const fn = (x: number) => x * 2;
177
217
 
178
218
  invokeIfFunction(fn, 5); // 10
179
219
  invokeIfFunction('not a function', 5); // 'not a function'
180
220
 
181
- // Create a promise that resolves after a specified delay
182
- await delay(1000); // Waits for 1 second before continuing
221
+ /**
222
+ * Waits for 1 second before continuing
223
+ */
224
+ await delay(1000);
183
225
 
184
- // Retry an async function with configurable options
226
+ /**
227
+ * Retry an async function with configurable options
228
+ */
185
229
  async function fetchData() {
186
230
  const response = await fetch('/api/data');
187
231
 
@@ -230,65 +274,95 @@ import {
230
274
  isSet
231
275
  } from '@react-hive/honey-utils';
232
276
 
233
- // Check if value is a string
277
+ /**
278
+ * Check if value is a string
279
+ */
234
280
  isString('hello'); // true
235
281
  isString(123); // false
236
282
 
237
- // Check if value is a number
283
+ /**
284
+ * Check if value is a number
285
+ */
238
286
  isNumber(123); // true
239
287
  isNumber('123'); // false
240
288
 
241
- // Check if value is a boolean
289
+ /**
290
+ * Check if value is a boolean
291
+ */
242
292
  isBool(true); // true
243
293
  isBool('true'); // false
244
294
 
245
- // Check if value is an object
295
+ /**
296
+ * Check if value is an object
297
+ */
246
298
  isObject({}); // true
247
299
  isObject('object'); // false
248
300
 
249
- // Check if value is a function
301
+ /**
302
+ * Check if value is a function
303
+ */
250
304
  isFunction(() => {}); // true
251
305
  isFunction({}); // false
252
306
 
253
- // Check if value is a Promise
307
+ /**
308
+ * Check if value is a Promise
309
+ */
254
310
  isPromise(Promise.resolve()); // true
255
311
  isPromise({}); // false
256
312
 
257
- // Check if value is null or undefined
313
+ /**
314
+ * Check if value is null or undefined
315
+ */
258
316
  isNil(null); // true
259
317
  isNil(undefined); // true
260
318
  isNil(''); // false
261
319
 
262
- // Check if value is null, undefined, or empty string
320
+ /**
321
+ * Check if value is null, undefined, or empty string
322
+ */
263
323
  isNilOrEmptyString(''); // true
264
324
  isNilOrEmptyString(null); // true
265
325
  isNilOrEmptyString('hello'); // false
266
326
 
267
- // Check if value is an array
327
+ /**
328
+ * Check if value is an array
329
+ */
268
330
  isArray([1, 2, 3]); // true
269
331
  isArray({}); // false
270
332
 
271
- // Check if value is an empty array
333
+ /**
334
+ * Check if value is an empty array
335
+ */
272
336
  isEmptyArray([]); // true
273
337
  isEmptyArray([1, 2, 3]); // false
274
338
 
275
- // Check if value is an empty object
339
+ /**
340
+ * Check if value is an empty object
341
+ */
276
342
  isEmptyObject({}); // true
277
343
  isEmptyObject({ key: 'value' }); // false
278
344
 
279
- // Check if value is a Date object
345
+ /**
346
+ * Check if value is a Date object
347
+ */
280
348
  isDate(new Date()); // true
281
349
  isDate('2023-01-01'); // false
282
350
 
283
- // Check if value is a valid Date object
351
+ /**
352
+ * Check if value is a valid Date object
353
+ */
284
354
  isValidDate(new Date()); // true
285
355
  isValidDate(new Date('invalid')); // false
286
356
 
287
- // Check if value is a RegExp
357
+ /**
358
+ * Check if value is a RegExp
359
+ */
288
360
  isRegExp(/test/); // true
289
361
  isRegExp('test'); // false
290
362
 
291
- // Check if value is a Map or Set
363
+ /**
364
+ * Check if value is a Map or Set
365
+ */
292
366
  isMap(new Map()); // true
293
367
  isSet(new Set()); // true
294
368
  ```
@@ -302,13 +376,19 @@ import {
302
376
  calculatePercentage
303
377
  } from '@react-hive/honey-utils';
304
378
 
305
- // Calculate Euclidean distance between two points
379
+ /**
380
+ * Calculate Euclidean distance between two points
381
+ */
306
382
  calculateEuclideanDistance(0, 0, 3, 4); // 5
307
383
 
308
- // Calculate moving speed
384
+ /**
385
+ * Calculate moving speed
386
+ */
309
387
  calculateMovingSpeed(100, 5); // 20
310
388
 
311
- // Calculate percentage of a value
389
+ /**
390
+ * Calculate percentage of a value
391
+ */
312
392
  calculatePercentage(200, 25); // 50
313
393
  ```
314
394
 
@@ -356,8 +436,6 @@ function divide(a: number, b: number): number {
356
436
 
357
437
  ## API Documentation
358
438
 
359
- ---
360
-
361
439
  ### String Utilities
362
440
 
363
441
  - `toKebabCase(input: string): string` - Converts a string to kebab-case.
@@ -367,23 +445,13 @@ function divide(a: number, b: number): number {
367
445
 
368
446
  ### Array Utilities
369
447
 
370
- #### Synchronous Utilities
371
-
372
448
  - `boolFilter<T>(array: (T | false | null | undefined)[]): T[]` - Filters out falsy values (`false`, `null`, `undefined`) from an array while keeping valid items.
373
449
  - `unique<T>(array: T[]): T[]` - Returns a new array with all duplicate elements removed. Keeps only the first occurrence of each value.
374
450
  - `chunk<T>(array: T[], size: number): T[][]` - Splits an array into smaller arrays ("chunks") of the specified size.
375
451
  - `intersection<T>(...arrays: T[][]): T[]` - Returns an array of elements that exist in all provided arrays.
376
452
  - `difference<T>(array: T[], exclude: T[]): T[]` - Returns a new array that contains items from `array` that are not present in `exclude`.
377
-
378
- #### Asynchronous Utilities
379
-
380
- - `forAsync<Item, Result>(array: Item[], callbackFn: (item, index, array) => Promise<Result>): Promise<Result[]>` - Runs asynchronous operations on each array item *sequentially* and returns the results in the original order.
381
- - `mapAsync<Item, Return>(array: Item[], callbackFn: (item, index, array) => Promise<Return>): Promise<Return[]>` - Executes an asynchronous function for each array item *in parallel* and returns a promise of all results.
382
- - `reduceAsync<Item, Accumulator>(array: Item[], callbackFn, initialValue): Promise<Accumulator>` - Asynchronously reduces an array to a single accumulated value. Each step waits for the previous promise to resolve.
383
- - `filterAsync<Item>(array: Item[], callbackFn): Promise<Item[]>` - Runs an asynchronous filter operation. Only includes items where `callbackFn(item)` resolves to `true`.
384
- - `someAsync<Item>(array: Item[], callbackFn): Promise<boolean>` - Returns `true` if **any** item in the array passes the async predicate.
385
- - `everyAsync<Item>(array: Item[], callbackFn): Promise<boolean>` - Returns `true` if **all** items in the array pass the async predicate.
386
- - `findAsync<Item>(array: Item[], callbackFn): Promise<Item | null>` - Returns the first array item that passes the async predicate, or `null` if no match is found.
453
+ - `pipe(...fns: Function[]): Function` - Composes unary functions left-to-right. Returns a new function that applies all given functions in a sequence.
454
+ - `compose(...fns: Function[]): Function` - Composes unary functions **right-to-left**. Same as `pipe`, but applies functions in reverse order.
387
455
 
388
456
  ### Function Utilities
389
457
 
@@ -395,32 +463,33 @@ function divide(a: number, b: number): number {
395
463
  ### Type Guards
396
464
 
397
465
  - `assert(condition: any, message: string): asserts condition` - Asserts that a condition is truthy, throwing an error with the provided message if it's not.
398
- - `isString(value: unknown): value is string` - Checks if a value is a string.
399
- - `isNumber(value: unknown): value is number` - Checks if a value is a number.
400
- - `isBool(value: unknown): value is boolean` - Checks if a value is a boolean.
401
- - `isObject(value: unknown): value is object` - Checks if a value is an object.
402
- - `isFunction(value: unknown): value is Function` - Checks if a value is a function.
403
- - `isPromise<T = unknown>(value: unknown): value is Promise<T>` - Checks if a value is a Promise.
404
- - `isNil(value: unknown): value is null | undefined` - Checks if a value is null or undefined.
405
- - `isNilOrEmptyString(value: unknown): value is null | undefined` - Checks if a value is null, undefined, or an empty string.
466
+ - `isString(value: unknown): value is string` - Checks if a value is a `string`.
467
+ - `isNumber(value: unknown): value is number` - Checks if a value is a `number`.
468
+ - `isBool(value: unknown): value is boolean` - Checks if a value is a `boolean`.
469
+ - `isObject(value: unknown): value is object` - Checks if a value is an `object`.
470
+ - `isFunction(value: unknown): value is Function` - Checks if a value is a `function`.
471
+ - `isPromise<T = unknown>(value: unknown): value is Promise<T>` - Checks if a value is a `Promise`.
472
+ - `isNil(value: unknown): value is null | undefined` - Checks if a value is `null` or `undefined`.
473
+ - `isNilOrEmptyString(value: unknown): value is null | undefined` - Checks if a value is `null`, `undefined`, or an empty string.
406
474
  - `isArray(value: unknown): value is unknown[]` - Checks if a value is an array.
407
475
  - `isEmptyArray(value: unknown): value is []` - Checks if a value is an empty array.
408
476
  - `isEmptyObject(value: unknown): value is Record<string, never>` - Checks if a value is an empty object.
409
- - `isNull(value: unknown): value is null` - Checks if a value is null.
410
- - `isUndefined(value: unknown): value is undefined` - Checks if a value is undefined.
477
+ - `isNull(value: unknown): value is null` - Checks if a value is `null`.
478
+ - `isUndefined(value: unknown): value is undefined` - Checks if a value is `undefined`.
479
+ - `isDefined<T>(value: T): value is NonNullable<T>` - Checks if a value is neither `null` nor `undefined`.
411
480
  - `isFiniteNumber(value: unknown): value is number` - Checks if a value is a finite number.
412
481
  - `isInteger(value: unknown): value is number` - Checks if a value is an integer.
413
- - `isDate(value: unknown): value is Date` - Checks if a value is a Date object.
414
- - `isValidDate(value: unknown): value is Date` - Checks if a value is a valid Date object (not Invalid Date).
415
- - `isRegExp(value: unknown): value is RegExp` - Checks if a value is a RegExp object.
416
- - `isMap(value: unknown): value is Map<unknown, unknown>` - Checks if a value is a Map.
417
- - `isSet(value: unknown): value is Set<unknown>` - Checks if a value is a Set.
418
- - `isSymbol(value: unknown): value is symbol` - Checks if a value is a Symbol.
482
+ - `isDate(value: unknown): value is Date` - Checks if a value is a `Date` object.
483
+ - `isValidDate(value: unknown): value is Date` - Checks if a value is a valid `Date` object.
484
+ - `isRegExp(value: unknown): value is RegExp` - Checks if a value is a `RegExp` object.
485
+ - `isMap(value: unknown): value is Map<unknown, unknown>` - Checks if a value is a `Map`.
486
+ - `isSet(value: unknown): value is Set<unknown>` - Checks if a value is a `Set`.
487
+ - `isSymbol(value: unknown): value is symbol` - Checks if a value is a `Symbol`.
419
488
 
420
489
  ### Math Utilities
421
490
 
422
491
  - `calculateEuclideanDistance(startX: number, startY: number, endX: number, endY: number): number` - Calculates the Euclidean distance between two points.
423
- - `calculateMovingSpeed(delta: number, elapsedTime: number): number` - Calculates moving speed.
492
+ - `calculateMovingSpeed(distance: number, elapsedTime: number): number` - Calculates moving speed.
424
493
  - `calculatePercentage(value: number, percentage: number): number` - Calculates the specified percentage of a value.
425
494
 
426
495
  ### DOM Utilities
@@ -429,6 +498,16 @@ function divide(a: number, b: number): number {
429
498
  - `cloneBlob(blob: Blob): Blob` - Creates a clone of a Blob object with the same content and type as the original.
430
499
  - `convertBlobToFile(blob: Blob, fileName: string): File` - Converts a Blob object into a File object with the specified name.
431
500
 
501
+ ### Asynchronous Utilities
502
+
503
+ - `runSequential<Item, Result>(array: Item[], fn: (item, index, array) => Promise<Result>): Promise<Result[]>` - Runs asynchronous operations on each array item *sequentially* and returns the results in the original order.
504
+ - `runParallel<Item, Result>(array: Item[], fn: (item, index, array) => Promise<Result>): Promise<Result[]>` - Executes an asynchronous function for each array item *in parallel* and returns a promise of all results.
505
+ - `reduceAsync<Item, Accumulator>(array: Item[], fn, initialValue): Promise<Accumulator>` - Asynchronously reduces an array to a single accumulated value. Each step waits for the previous promise to resolve.
506
+ - `filterAsync<Item>(array: Item[], predicate): Promise<Item[]>` - Runs an asynchronous filter operation. Only includes items where `predicate(item)` resolves to `true`.
507
+ - `someAsync<Item>(array: Item[], predicate): Promise<boolean>` - Returns `true` if **any** item in the array passes the async predicate.
508
+ - `everyAsync<Item>(array: Item[], predicate): Promise<boolean>` - Returns `true` if **all** items in the array pass the async predicate.
509
+ - `findAsync<Item>(array: Item[], predicate): Promise<Item | null>` - Returns the first array item that passes the async predicate, or `null` if no match is found.
510
+
432
511
  ## Contributing
433
512
 
434
513
  Contributions are welcome! Please feel free to submit a Pull Request.