@tim-code/my-util 0.5.11 → 0.5.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tim-code/my-util",
3
- "version": "0.5.11",
3
+ "version": "0.5.13",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "author": "Tim Sprowl",
package/src/array.js CHANGED
@@ -1,22 +1,28 @@
1
1
  /**
2
- * Converts an array into an array of arrays, where each subarray has a maximum size of chunkSize.
2
+ * Converts an iterable into an array of arrays, where each subarray has a maximum size of chunkSize.
3
3
  * Note the last subarray may have a length less than chunkSize.
4
- * @param {Array} array
5
- * @param {number=} chunkSize If not provided, defaults to the length of array, returning the input array as one chunk.
4
+ * If the iterable has no elements, returns an empty array since there are no chunks.
5
+ * @param {Iterable} iterable
6
+ * @param {number=} chunkSize If not provided, returns an array consisting of one chunk, which has all the elements of input iterable.
6
7
  * @returns {Array}
7
8
  */
8
- export function chunk(array, chunkSize = array.length) {
9
- if (!array.length) {
10
- return []
9
+ export function chunk(iterable, chunkSize = Infinity) {
10
+ if (chunkSize !== Infinity && (chunkSize <= 0 || chunkSize % 1 !== 0)) {
11
+ throw new Error("chunkSize must be a positive integer or Infinity")
11
12
  }
12
- if (chunkSize <= 0 || chunkSize % 1 !== 0) {
13
- throw new Error("chunkSize must be a positive integer")
13
+ const chunks = []
14
+ let currentChunk = []
15
+ for (const element of iterable) {
16
+ currentChunk.push(element)
17
+ if (currentChunk.length >= chunkSize) {
18
+ chunks.push(currentChunk)
19
+ currentChunk = []
20
+ }
14
21
  }
15
- const chunked = []
16
- for (let i = 0; i < array.length; i += chunkSize) {
17
- chunked.push(array.slice(i, i + chunkSize))
22
+ if (currentChunk.length) {
23
+ chunks.push(currentChunk)
18
24
  }
19
- return chunked
25
+ return chunks
20
26
  }
21
27
 
22
28
  /**
package/src/array.test.js CHANGED
@@ -22,14 +22,20 @@ describe("chunk", () => {
22
22
  expect(chunk([1, 2], 2)).toEqual([[1, 2]])
23
23
  })
24
24
 
25
- it("returns the entire array as one chunk if chunkSize is omitted", () => {
25
+ it("returns the entire iterable as one chunk if chunkSize is omitted", () => {
26
26
  expect(chunk([1, 2, 3])).toEqual([[1, 2, 3]])
27
27
  })
28
28
 
29
- it("throws if chunkSize is not a positive integer", () => {
30
- expect(() => chunk([1, 2, 3], 0)).toThrow("chunkSize must be a positive integer")
31
- expect(() => chunk([1, 2, 3], -1)).toThrow("chunkSize must be a positive integer")
32
- expect(() => chunk([1, 2, 3], 1.5)).toThrow("chunkSize must be a positive integer")
29
+ it("throws if chunkSize is not a positive integer or Infinity", () => {
30
+ expect(() => chunk([1, 2, 3], 0)).toThrow(
31
+ /chunkSize must be a positive integer or Infinity/u
32
+ )
33
+ expect(() => chunk([1, 2, 3], -1)).toThrow(
34
+ /chunkSize must be a positive integer or Infinity/u
35
+ )
36
+ expect(() => chunk([1, 2, 3], 1.5)).toThrow(
37
+ /chunkSize must be a positive integer or Infinity/u
38
+ )
33
39
  })
34
40
 
35
41
  it("handles chunkSize of 1 (each element in its own chunk)", () => {
@@ -43,6 +49,40 @@ describe("chunk", () => {
43
49
  it("returns one chunk if chunkSize is much larger than array length", () => {
44
50
  expect(chunk([1, 2, 3], 100)).toEqual([[1, 2, 3]])
45
51
  })
52
+
53
+ it("works with Map iterables and chunks entries", () => {
54
+ const m = new Map([
55
+ ["a", 1],
56
+ ["b", 2],
57
+ ["c", 3],
58
+ ["d", 4],
59
+ ["e", 5],
60
+ ])
61
+ expect(chunk(m, 2)).toEqual([
62
+ [
63
+ ["a", 1],
64
+ ["b", 2],
65
+ ],
66
+ [
67
+ ["c", 3],
68
+ ["d", 4],
69
+ ],
70
+ [["e", 5]],
71
+ ])
72
+ })
73
+
74
+ it("works with non-array iterables when chunkSize is omitted (single chunk of entries)", () => {
75
+ const m = new Map([
76
+ ["a", 1],
77
+ ["b", 2],
78
+ ])
79
+ expect(chunk(m)).toEqual([
80
+ [
81
+ ["a", 1],
82
+ ["b", 2],
83
+ ],
84
+ ])
85
+ })
46
86
  })
47
87
 
48
88
  describe("unique", () => {
package/src/promise.js CHANGED
@@ -72,12 +72,12 @@ export async function sleep(ms) {
72
72
  * @param {boolean=} $1.flatten Flattens values before returning; useful if promises return arrays
73
73
  * @param {boolean=} $1.abort If true, will return early if there are errors.
74
74
  * If false (default), will process all elements in the array (like Promise.allSettled()).
75
- * @param {Function} callback
75
+ * @param {Function} callback Default is identity function to enable passing promises as "array".
76
76
  * @returns {Object} {results, values, returned, errors}
77
77
  */
78
78
  export async function allSettled(
79
79
  { array, limit, limiter, flatten = false, abort = false },
80
- callback
80
+ callback = (promise) => promise
81
81
  ) {
82
82
  const results = []
83
83
  let returned = []
@@ -132,6 +132,15 @@ describe("allSettled", () => {
132
132
  expect(result.results.every((r) => r.status === "fulfilled")).toBe(true)
133
133
  })
134
134
 
135
+ it("returns correct structure for all fulfilled", async () => {
136
+ const arr = [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)]
137
+ const result = await allSettled({ array: arr })
138
+ expect(result.values).toEqual([1, 2, 3])
139
+ expect(result.returned).toEqual([1, 2, 3])
140
+ expect(result.errors).toEqual([])
141
+ expect(result.results.every((r) => r.status === "fulfilled")).toBe(true)
142
+ })
143
+
135
144
  it("handles rejected promises and collects errors", async () => {
136
145
  const arr = [1, 2, 3]
137
146
  const cb = (x) => (x === 2 ? Promise.reject("fail") : x + 1)