complete-common 2.11.0 → 2.13.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.
@@ -51,6 +51,20 @@ export declare function arrayRemoveAllInPlace<T>(array: T[], ...elementsToRemove
51
51
  export declare function arrayRemoveInPlace<T>(array: T[], ...elementsToRemove: readonly T[]): readonly T[];
52
52
  /** Helper function to remove all of the elements in an array in-place. */
53
53
  export declare function emptyArray(array: unknown[]): void;
54
+ /**
55
+ * Helper function to perform an asynchronous filter. The vanilla `Array.filter` method does not
56
+ * wait for promises (and treats them as truthy), so this function runs the predicate on all
57
+ * elements concurrently, awaits the results, and then filters the original array.
58
+ *
59
+ * Usage:
60
+ *
61
+ * ```ts
62
+ * const results = await filterAsync(things, async (thing) => await filterFunc(thing));
63
+ * ```
64
+ *
65
+ * (This is an abstraction around `Promise.all`.)
66
+ */
67
+ export declare function filterAsync<T>(array: readonly T[], predicate: (element: T) => Promise<boolean>): Promise<readonly T[]>;
54
68
  /**
55
69
  * Helper function to perform a filter and a map at the same time. Similar to `Array.map`, provide a
56
70
  * function that transforms a value, but return `undefined` if the value should be skipped. (Thus,
@@ -63,6 +77,26 @@ export declare function emptyArray(array: unknown[]): void;
63
77
  * https://doc.rust-lang.org/std/iter/struct.FilterMap.html
64
78
  */
65
79
  export declare function filterMap<OldT, NewT>(array: readonly OldT[], func: (element: OldT) => NewT | undefined): readonly NewT[];
80
+ /**
81
+ * Helper function to perform a filter and a map at the same time. Similar to `Array.map`, provide a
82
+ * function that transforms a value, but return `undefined` if the value should be skipped. (Thus,
83
+ * this function cannot be used in situations where `undefined` can be a valid array element.)
84
+ *
85
+ * This function is useful because the `Array.map` method will always produce an array with the same
86
+ * amount of elements as the original array.
87
+ *
88
+ * This is named `filterMap` after the Rust function:
89
+ * https://doc.rust-lang.org/std/iter/struct.FilterMap.html
90
+ *
91
+ * This is the asynchronous version, which can be used like this:
92
+ *
93
+ * ```ts
94
+ * const results = await asyncFilterMap(things, someFunc);
95
+ * ```
96
+ *
97
+ * (This is an abstraction around `Promise.all`.)
98
+ */
99
+ export declare function filterMapAsync<OldT, NewT>(array: readonly OldT[], func: (element: OldT) => Promise<NewT | undefined>): Promise<readonly NewT[]>;
66
100
  /**
67
101
  * Helper function to get a random element from the provided array.
68
102
  *
@@ -51,6 +51,20 @@ export declare function arrayRemoveAllInPlace<T>(array: T[], ...elementsToRemove
51
51
  export declare function arrayRemoveInPlace<T>(array: T[], ...elementsToRemove: readonly T[]): readonly T[];
52
52
  /** Helper function to remove all of the elements in an array in-place. */
53
53
  export declare function emptyArray(array: unknown[]): void;
54
+ /**
55
+ * Helper function to perform an asynchronous filter. The vanilla `Array.filter` method does not
56
+ * wait for promises (and treats them as truthy), so this function runs the predicate on all
57
+ * elements concurrently, awaits the results, and then filters the original array.
58
+ *
59
+ * Usage:
60
+ *
61
+ * ```ts
62
+ * const results = await filterAsync(things, async (thing) => await filterFunc(thing));
63
+ * ```
64
+ *
65
+ * (This is an abstraction around `Promise.all`.)
66
+ */
67
+ export declare function filterAsync<T>(array: readonly T[], predicate: (element: T) => Promise<boolean>): Promise<readonly T[]>;
54
68
  /**
55
69
  * Helper function to perform a filter and a map at the same time. Similar to `Array.map`, provide a
56
70
  * function that transforms a value, but return `undefined` if the value should be skipped. (Thus,
@@ -63,6 +77,26 @@ export declare function emptyArray(array: unknown[]): void;
63
77
  * https://doc.rust-lang.org/std/iter/struct.FilterMap.html
64
78
  */
65
79
  export declare function filterMap<OldT, NewT>(array: readonly OldT[], func: (element: OldT) => NewT | undefined): readonly NewT[];
80
+ /**
81
+ * Helper function to perform a filter and a map at the same time. Similar to `Array.map`, provide a
82
+ * function that transforms a value, but return `undefined` if the value should be skipped. (Thus,
83
+ * this function cannot be used in situations where `undefined` can be a valid array element.)
84
+ *
85
+ * This function is useful because the `Array.map` method will always produce an array with the same
86
+ * amount of elements as the original array.
87
+ *
88
+ * This is named `filterMap` after the Rust function:
89
+ * https://doc.rust-lang.org/std/iter/struct.FilterMap.html
90
+ *
91
+ * This is the asynchronous version, which can be used like this:
92
+ *
93
+ * ```ts
94
+ * const results = await asyncFilterMap(things, someFunc);
95
+ * ```
96
+ *
97
+ * (This is an abstraction around `Promise.all`.)
98
+ */
99
+ export declare function filterMapAsync<OldT, NewT>(array: readonly OldT[], func: (element: OldT) => Promise<NewT | undefined>): Promise<readonly NewT[]>;
66
100
  /**
67
101
  * Helper function to get a random element from the provided array.
68
102
  *
@@ -51,6 +51,20 @@ export declare function arrayRemoveAllInPlace<T>(array: T[], ...elementsToRemove
51
51
  export declare function arrayRemoveInPlace<T>(array: T[], ...elementsToRemove: readonly T[]): readonly T[];
52
52
  /** Helper function to remove all of the elements in an array in-place. */
53
53
  export declare function emptyArray(array: unknown[]): void;
54
+ /**
55
+ * Helper function to perform an asynchronous filter. The vanilla `Array.filter` method does not
56
+ * wait for promises (and treats them as truthy), so this function runs the predicate on all
57
+ * elements concurrently, awaits the results, and then filters the original array.
58
+ *
59
+ * Usage:
60
+ *
61
+ * ```ts
62
+ * const results = await filterAsync(things, async (thing) => await filterFunc(thing));
63
+ * ```
64
+ *
65
+ * (This is an abstraction around `Promise.all`.)
66
+ */
67
+ export declare function filterAsync<T>(array: readonly T[], predicate: (element: T) => Promise<boolean>): Promise<readonly T[]>;
54
68
  /**
55
69
  * Helper function to perform a filter and a map at the same time. Similar to `Array.map`, provide a
56
70
  * function that transforms a value, but return `undefined` if the value should be skipped. (Thus,
@@ -63,6 +77,26 @@ export declare function emptyArray(array: unknown[]): void;
63
77
  * https://doc.rust-lang.org/std/iter/struct.FilterMap.html
64
78
  */
65
79
  export declare function filterMap<OldT, NewT>(array: readonly OldT[], func: (element: OldT) => NewT | undefined): readonly NewT[];
80
+ /**
81
+ * Helper function to perform a filter and a map at the same time. Similar to `Array.map`, provide a
82
+ * function that transforms a value, but return `undefined` if the value should be skipped. (Thus,
83
+ * this function cannot be used in situations where `undefined` can be a valid array element.)
84
+ *
85
+ * This function is useful because the `Array.map` method will always produce an array with the same
86
+ * amount of elements as the original array.
87
+ *
88
+ * This is named `filterMap` after the Rust function:
89
+ * https://doc.rust-lang.org/std/iter/struct.FilterMap.html
90
+ *
91
+ * This is the asynchronous version, which can be used like this:
92
+ *
93
+ * ```ts
94
+ * const results = await asyncFilterMap(things, someFunc);
95
+ * ```
96
+ *
97
+ * (This is an abstraction around `Promise.all`.)
98
+ */
99
+ export declare function filterMapAsync<OldT, NewT>(array: readonly OldT[], func: (element: OldT) => Promise<NewT | undefined>): Promise<readonly NewT[]>;
66
100
  /**
67
101
  * Helper function to get a random element from the provided array.
68
102
  *
@@ -1 +1 @@
1
- {"version":3,"file":"array.d.ts","sourceRoot":"","sources":["../../src/functions/array.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAI7D;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EACvC,KAAK,EAAE,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC,GACjC,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC,CAQ7B;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAC3B,MAAM,EAAE,SAAS,CAAC,EAAE,EACpB,MAAM,EAAE,SAAS,CAAC,EAAE,GACnB,OAAO,CAST;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAC3B,aAAa,EAAE,SAAS,CAAC,EAAE,EAC3B,GAAG,gBAAgB,EAAE,SAAS,CAAC,EAAE,GAChC,SAAS,CAAC,EAAE,CAWd;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAErC,KAAK,EAAE,CAAC,EAAE,EACV,GAAG,gBAAgB,EAAE,SAAS,CAAC,EAAE,GAChC,OAAO,CAeT;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAElC,KAAK,EAAE,CAAC,EAAE,EACV,GAAG,gBAAgB,EAAE,SAAS,CAAC,EAAE,GAChC,SAAS,CAAC,EAAE,CAYd;AAED,0EAA0E;AAE1E,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,IAAI,CAEjD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,EAClC,KAAK,EAAE,SAAS,IAAI,EAAE,EACtB,IAAI,EAAE,CAAC,OAAO,EAAE,IAAI,KAAK,IAAI,GAAG,SAAS,GACxC,SAAS,IAAI,EAAE,CAWjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,UAAU,GAAE,SAAS,CAAC,EAAO,GAC5B,CAAC,CAiBH;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,SAAS,OAAO,EAAE,EACzB,UAAU,GAAE,SAAS,MAAM,EAAO,GACjC,MAAM,CAQR;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,YAAY,SAAS,YAAY,CAAC,CAAC,CAAC,EAC9D,KAAK,EAAE,SAAS,YAAY,EAAE,EAC9B,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC,GAC7B,aAAa,IAAI,YAAY,CAG/B;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAC3B,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,GAAG,cAAc,EAAE,SAAS,CAAC,EAAE,GAC9B,OAAO,CAET;AAED,uFAAuF;AACvF,wBAAgB,OAAO,CAAC,QAAQ,EAAE,OAAO,GAAG,QAAQ,IAAI,OAAO,EAAE,CAEhE;AAED,kFAAkF;AAClF,wBAAgB,cAAc,CAAC,QAAQ,EAAE,OAAO,GAAG,QAAQ,IAAI,OAAO,EAAE,CAMvE;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,GAAG,QAAQ,IAAI,MAAM,EAAE,CAMrE;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,GAAG,QAAQ,IAAI,MAAM,EAAE,CAMrE;AAED,qFAAqF;AACrF,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,SAAS,CAAC,EAAE,CAElE;AAED,+DAA+D;AAC/D,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAEzD"}
1
+ {"version":3,"file":"array.d.ts","sourceRoot":"","sources":["../../src/functions/array.ts"],"names":[],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -188,6 +188,12 @@ function arrayRemoveInPlace(array, ...elementsToRemove) {
188
188
  function emptyArray(array) {
189
189
  array.splice(0);
190
190
  }
191
+ async function filterAsync(array, predicate) {
192
+ const results = await Promise.all(
193
+ array.map(async (element) => await predicate(element))
194
+ );
195
+ return array.filter((_, index) => results[index] === true);
196
+ }
191
197
  function filterMap(array, func) {
192
198
  const filteredArray = [];
193
199
  for (const element of array) {
@@ -198,6 +204,11 @@ function filterMap(array, func) {
198
204
  }
199
205
  return filteredArray;
200
206
  }
207
+ async function filterMapAsync(array, func) {
208
+ const promises = array.map(async (element) => await func(element));
209
+ const results = await Promise.all(promises);
210
+ return results.filter((item) => item !== void 0);
211
+ }
201
212
  function getRandomArrayElement(array, exceptions = []) {
202
213
  if (array.length === 0) {
203
214
  throw new Error(
@@ -621,7 +632,9 @@ exports.copySet = copySet;
621
632
  exports.eRange = eRange;
622
633
  exports.emptyArray = emptyArray;
623
634
  exports.escapeHTMLCharacters = escapeHTMLCharacters;
635
+ exports.filterAsync = filterAsync;
624
636
  exports.filterMap = filterMap;
637
+ exports.filterMapAsync = filterMapAsync;
625
638
  exports.getElapsedSeconds = getElapsedSeconds;
626
639
  exports.getEnumEntries = getEnumEntries;
627
640
  exports.getEnumKeys = getEnumKeys;
package/dist/index.mjs CHANGED
@@ -186,6 +186,12 @@ function arrayRemoveInPlace(array, ...elementsToRemove) {
186
186
  function emptyArray(array) {
187
187
  array.splice(0);
188
188
  }
189
+ async function filterAsync(array, predicate) {
190
+ const results = await Promise.all(
191
+ array.map(async (element) => await predicate(element))
192
+ );
193
+ return array.filter((_, index) => results[index] === true);
194
+ }
189
195
  function filterMap(array, func) {
190
196
  const filteredArray = [];
191
197
  for (const element of array) {
@@ -196,6 +202,11 @@ function filterMap(array, func) {
196
202
  }
197
203
  return filteredArray;
198
204
  }
205
+ async function filterMapAsync(array, func) {
206
+ const promises = array.map(async (element) => await func(element));
207
+ const results = await Promise.all(promises);
208
+ return results.filter((item) => item !== void 0);
209
+ }
199
210
  function getRandomArrayElement(array, exceptions = []) {
200
211
  if (array.length === 0) {
201
212
  throw new Error(
@@ -586,4 +597,4 @@ function* tupleKeys(tuple) {
586
597
 
587
598
  const ReadonlyMap = Map;
588
599
 
589
- export { HOUR_IN_MILLISECONDS, MINUTE_IN_MILLISECONDS, ReadonlyMap, ReadonlySet, SECOND_IN_MILLISECONDS, addSetsToSet, arrayCopyTwoDimensional, arrayEquals, arrayRemove, arrayRemoveAllInPlace, arrayRemoveInPlace, assertArray, assertArrayBoolean, assertArrayNumber, assertArrayObject, assertArrayString, assertBoolean, assertDefined, assertEnumValue, assertInteger, assertIs, assertNotNull, assertNumber, assertObject, assertString, assertStringNotEmpty, capitalizeFirstLetter, clamp, combineSets, copySet, eRange, emptyArray, escapeHTMLCharacters, filterMap, getElapsedSeconds, getEnumEntries, getEnumKeys, getEnumValues, getNumConsecutiveDiacritics, getRandomArrayElement, getRandomArrayIndex, getRandomInt, hasDiacritic, hasEmoji, hasWhitespace, iRange, includes, includesAny, interfaceSatisfiesEnum, isASCII, isArray, isArrayBoolean, isArrayNumber, isArrayString, isEnumValue, isFirstLetterCapitalized, isKebabCase, isKeyOf, isLowerCase, isObject, isSemanticVersion, isUpperCase, kebabCaseToCamelCase, kebabCaseToPascalCase, mapFilter, mapFind, newArray, noop, normalizeString, objectFilter, objectKeysToSet, objectToMap, objectToReverseMap, objectValuesToSet, parseFloatSafe, parseIntSafe, parseSemanticVersion, removeLinesBetweenMarkers, removeLinesMatching, removeNonPrintableCharacters, removeWhitespace, repeat, setAdd, setHas, sortCaseInsensitive, sumArray, todo, trimPrefix, trimSuffix, truncateString, tupleEntries, tupleKeys };
600
+ export { HOUR_IN_MILLISECONDS, MINUTE_IN_MILLISECONDS, ReadonlyMap, ReadonlySet, SECOND_IN_MILLISECONDS, addSetsToSet, arrayCopyTwoDimensional, arrayEquals, arrayRemove, arrayRemoveAllInPlace, arrayRemoveInPlace, assertArray, assertArrayBoolean, assertArrayNumber, assertArrayObject, assertArrayString, assertBoolean, assertDefined, assertEnumValue, assertInteger, assertIs, assertNotNull, assertNumber, assertObject, assertString, assertStringNotEmpty, capitalizeFirstLetter, clamp, combineSets, copySet, eRange, emptyArray, escapeHTMLCharacters, filterAsync, filterMap, filterMapAsync, getElapsedSeconds, getEnumEntries, getEnumKeys, getEnumValues, getNumConsecutiveDiacritics, getRandomArrayElement, getRandomArrayIndex, getRandomInt, hasDiacritic, hasEmoji, hasWhitespace, iRange, includes, includesAny, interfaceSatisfiesEnum, isASCII, isArray, isArrayBoolean, isArrayNumber, isArrayString, isEnumValue, isFirstLetterCapitalized, isKebabCase, isKeyOf, isLowerCase, isObject, isSemanticVersion, isUpperCase, kebabCaseToCamelCase, kebabCaseToPascalCase, mapFilter, mapFind, newArray, noop, normalizeString, objectFilter, objectKeysToSet, objectToMap, objectToReverseMap, objectValuesToSet, parseFloatSafe, parseIntSafe, parseSemanticVersion, removeLinesBetweenMarkers, removeLinesMatching, removeNonPrintableCharacters, removeWhitespace, repeat, setAdd, setHas, sortCaseInsensitive, sumArray, todo, trimPrefix, trimSuffix, truncateString, tupleEntries, tupleKeys };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "complete-common",
3
- "version": "2.11.0",
3
+ "version": "2.13.0",
4
4
  "description": "Helper functions for TypeScript projects.",
5
5
  "homepage": "https://complete-ts.github.io/",
6
6
  "bugs": {
@@ -28,14 +28,14 @@
28
28
  "build": "tsx ./scripts/build.ts",
29
29
  "docs": "typedoc",
30
30
  "lint": "tsx ./scripts/lint.ts",
31
- "test": "tsx --test"
31
+ "test": "tsx --test \"src/**/*.test.ts\""
32
32
  },
33
33
  "devDependencies": {
34
- "@types/node": "24.10.2",
35
- "complete-node": "13.0.0",
34
+ "@types/node": "25.0.3",
35
+ "complete-node": "16.2.0",
36
36
  "eslint-plugin-sort-exports": "0.9.1",
37
37
  "typescript": "5.9.3",
38
- "typescript-eslint": "8.49.0",
38
+ "typescript-eslint": "8.52.0",
39
39
  "unbuild": "3.6.1"
40
40
  }
41
41
  }
@@ -136,6 +136,30 @@ export function emptyArray(array: unknown[]): void {
136
136
  array.splice(0);
137
137
  }
138
138
 
139
+ /**
140
+ * Helper function to perform an asynchronous filter. The vanilla `Array.filter` method does not
141
+ * wait for promises (and treats them as truthy), so this function runs the predicate on all
142
+ * elements concurrently, awaits the results, and then filters the original array.
143
+ *
144
+ * Usage:
145
+ *
146
+ * ```ts
147
+ * const results = await filterAsync(things, async (thing) => await filterFunc(thing));
148
+ * ```
149
+ *
150
+ * (This is an abstraction around `Promise.all`.)
151
+ */
152
+ export async function filterAsync<T>(
153
+ array: readonly T[],
154
+ predicate: (element: T) => Promise<boolean>,
155
+ ): Promise<readonly T[]> {
156
+ const results = await Promise.all(
157
+ array.map(async (element) => await predicate(element)),
158
+ );
159
+
160
+ return array.filter((_, index) => results[index] === true);
161
+ }
162
+
139
163
  /**
140
164
  * Helper function to perform a filter and a map at the same time. Similar to `Array.map`, provide a
141
165
  * function that transforms a value, but return `undefined` if the value should be skipped. (Thus,
@@ -163,6 +187,34 @@ export function filterMap<OldT, NewT>(
163
187
  return filteredArray;
164
188
  }
165
189
 
190
+ /**
191
+ * Helper function to perform a filter and a map at the same time. Similar to `Array.map`, provide a
192
+ * function that transforms a value, but return `undefined` if the value should be skipped. (Thus,
193
+ * this function cannot be used in situations where `undefined` can be a valid array element.)
194
+ *
195
+ * This function is useful because the `Array.map` method will always produce an array with the same
196
+ * amount of elements as the original array.
197
+ *
198
+ * This is named `filterMap` after the Rust function:
199
+ * https://doc.rust-lang.org/std/iter/struct.FilterMap.html
200
+ *
201
+ * This is the asynchronous version, which can be used like this:
202
+ *
203
+ * ```ts
204
+ * const results = await asyncFilterMap(things, someFunc);
205
+ * ```
206
+ *
207
+ * (This is an abstraction around `Promise.all`.)
208
+ */
209
+ export async function filterMapAsync<OldT, NewT>(
210
+ array: readonly OldT[],
211
+ func: (element: OldT) => Promise<NewT | undefined>,
212
+ ): Promise<readonly NewT[]> {
213
+ const promises = array.map(async (element) => await func(element));
214
+ const results = await Promise.all(promises);
215
+ return results.filter((item) => item !== undefined);
216
+ }
217
+
166
218
  /**
167
219
  * Helper function to get a random element from the provided array.
168
220
  *