diff options
author | João Augusto Costa Branco Marado Torres <torres.dev@disroot.org> | 2025-06-24 12:08:41 -0300 |
---|---|---|
committer | João Augusto Costa Branco Marado Torres <torres.dev@disroot.org> | 2025-06-24 12:50:43 -0300 |
commit | f9a77c5c27aede4e5978eb55d9b7af781b680a1d (patch) | |
tree | d545e325ba1ae756fc2eac66fac1001b6753c40d /src/utils/iterator.ts |
feat!: initial commit
Signed-off-by: João Augusto Costa Branco Marado Torres <torres.dev@disroot.org>
Diffstat (limited to 'src/utils/iterator.ts')
-rw-r--r-- | src/utils/iterator.ts | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/utils/iterator.ts b/src/utils/iterator.ts new file mode 100644 index 0000000..fa58fc9 --- /dev/null +++ b/src/utils/iterator.ts @@ -0,0 +1,52 @@ +export type MaybeIterable<T> = T | Iterable<T>; +export type NonEmptyArray<T> = [T, ...T[]]; +export type AsyncYieldType<T> = T extends AsyncGenerator<infer U> ? U : never; + +export function surelyIterable<T>(maybe: MaybeIterable<T>): Iterable<T> { + return typeof maybe === "object" && maybe !== null && Symbol.iterator in maybe + ? maybe + : [maybe]; +} + +export async function* createAsyncIterator<T>( + promises: Promise<T>[], +): AsyncGenerator<T, void, void> { + for (const promise of promises) { + yield promise; + } +} + +export function filterDuplicate<T, K>( + array: Iterable<T>, + key: (i: T) => K, +): T[] { + const seen = new Map<K, T>(); + for (const i of array) { + const id = key(i); + if (!seen.has(id)) { + seen.set(id, i); + } + } + return Array.from(seen.values()); +} + +export async function findMapAsync<T, R>( + iter: Iterable<T>, + predicate: (value: T) => Promise<R>, +): Promise<R | undefined> { + const arr = Array.from(iter); + + async function tryNext(index: number): Promise<R | undefined> { + if (index >= arr.length) { + return await Promise.resolve(undefined); + } + + try { + return await predicate(arr[index]); + } catch { + return tryNext(index + 1); + } + } + + return await tryNext(0); +} |