From 5497f764ef219c1e86d227d28d9eb0832a088356 Mon Sep 17 00:00:00 2001 From: Gorniaky Date: Mon, 24 Aug 2026 18:20:06 -0300 Subject: [PATCH] build: implement Array.fromAsync for async iterable support --- packages/util/src/@prototypes/array.ts | 30 ++++++++++++++++++++++++++ packages/util/src/@prototypes/index.ts | 1 + packages/util/src/glob/fsGlob.ts | 3 +-- packages/util/src/glob/glob.ts | 3 +-- packages/util/src/glob/ignore.ts | 3 +-- packages/util/src/index.ts | 1 + packages/util/src/utils/array.ts | 16 -------------- 7 files changed, 35 insertions(+), 22 deletions(-) create mode 100644 packages/util/src/@prototypes/array.ts create mode 100644 packages/util/src/@prototypes/index.ts delete mode 100644 packages/util/src/utils/array.ts diff --git a/packages/util/src/@prototypes/array.ts b/packages/util/src/@prototypes/array.ts new file mode 100644 index 000000000..5f1703ede --- /dev/null +++ b/packages/util/src/@prototypes/array.ts @@ -0,0 +1,30 @@ +async function fromAsync( + iterableOrArrayLike: AsyncIterable | Iterable> | ArrayLike>, +) { + const array: T[] = []; + for await (const element of await iterableOrArrayLike as AsyncGenerator>) { + array.push(await element); + } + return array; +} + +async function mappedFromAsync( + iterableOrArrayLike: AsyncIterable | Iterable> | ArrayLike>, + mapFn: (value: Awaited, index: number) => U, +) { + const array: U[] = []; + for await (const element of await iterableOrArrayLike as AsyncGenerator>) { + array.push(mapFn(await element, array.length)); + } + return array; +} + +/** + * Designed for Node.js 20 compatibility + */ +Array.fromAsync ??= ( + iterableOrArrayLike: AsyncIterable | Iterable> | ArrayLike>, + mapFn?: (value: Awaited, index: number) => U, +) => typeof mapFn === "function" + ? mappedFromAsync(iterableOrArrayLike, mapFn) + : fromAsync(iterableOrArrayLike); diff --git a/packages/util/src/@prototypes/index.ts b/packages/util/src/@prototypes/index.ts new file mode 100644 index 000000000..6f174cd9f --- /dev/null +++ b/packages/util/src/@prototypes/index.ts @@ -0,0 +1 @@ +import "./array"; diff --git a/packages/util/src/glob/fsGlob.ts b/packages/util/src/glob/fsGlob.ts index ed9735b56..e7e375e4e 100644 --- a/packages/util/src/glob/fsGlob.ts +++ b/packages/util/src/glob/fsGlob.ts @@ -1,7 +1,6 @@ import { type Dirent } from "fs"; import { stat } from "fs/promises"; import { join } from "path"; -import { asyncGeneratorToArray } from "../utils/array"; import { DISCLOUD_IGNORE_FILENAME } from "./constants"; import { Ignore } from "./ignore"; import type { FSGlobOptions, FSGlobOptionsWithFileTypes, FSGlobOptionsWithoutFileTypes } from "./types"; @@ -10,7 +9,7 @@ export function fsGlob(pattern: string | string[], options?: FSGlobOptionsWithou export function fsGlob(pattern: string | string[], options?: FSGlobOptionsWithFileTypes): Promise export function fsGlob(pattern: string | string[], options?: FSGlobOptions): Promise> export function fsGlob(pattern: string | string[], options?: any): Promise { - return asyncGeneratorToArray(fsGlobIterate(pattern, options)); + return Array.fromAsync(fsGlobIterate(pattern, options)); } export function fsGlobIterate(pattern: string | string[], options?: FSGlobOptionsWithoutFileTypes): AsyncGenerator diff --git a/packages/util/src/glob/glob.ts b/packages/util/src/glob/glob.ts index 902684c3c..c69ab3466 100644 --- a/packages/util/src/glob/glob.ts +++ b/packages/util/src/glob/glob.ts @@ -1,11 +1,10 @@ import * as globMudule from "glob"; import { type } from "os"; -import { asyncGeneratorToArray } from "../utils/array"; import { DISCLOUD_IGNORE_FILENAME } from "./constants"; import { Ignore } from "./ignore"; export function glob(pattern: string | string[], cwd?: string) { - return asyncGeneratorToArray(globIterate(pattern, cwd)); + return Array.fromAsync(globIterate(pattern, cwd)); } export async function* globIterate(pattern: string | string[], cwd?: string) { diff --git a/packages/util/src/glob/ignore.ts b/packages/util/src/glob/ignore.ts index 1c5f41e7d..d813227d8 100644 --- a/packages/util/src/glob/ignore.ts +++ b/packages/util/src/glob/ignore.ts @@ -4,7 +4,6 @@ import { globIterate } from "glob"; import { globifyGitIgnore } from "globify-gitignore"; import { dirname } from "path"; import { joinWithRoot } from "../path"; -import { asyncGeneratorToArray } from "../utils/array"; export class Ignore { static async globify(content: string, directory?: string, absolute?: boolean) { @@ -58,7 +57,7 @@ export class Ignore { ) { } getIgnorePatterns(cwd?: string) { - return asyncGeneratorToArray(this._getIgnoreIterate(cwd)).then((value) => value.flat()); + return Array.fromAsync(this._getIgnoreIterate(cwd)).then((value) => value.flat()); } protected async* _getIgnoreIterate(cwd?: string) { diff --git a/packages/util/src/index.ts b/packages/util/src/index.ts index be73f9540..c5563b5db 100644 --- a/packages/util/src/index.ts +++ b/packages/util/src/index.ts @@ -1,4 +1,5 @@ import "source-map-support/register"; +import "./@prototypes"; export * from "./BitField"; export * from "./config"; diff --git a/packages/util/src/utils/array.ts b/packages/util/src/utils/array.ts deleted file mode 100644 index 66e90814c..000000000 --- a/packages/util/src/utils/array.ts +++ /dev/null @@ -1,16 +0,0 @@ -const arrayHasFromAsyncFunction = typeof Array.fromAsync === "function"; - -/** - * Designed for Node.js 20 compatibility - */ -export async function asyncGeneratorToArray(generator: AsyncGenerator) { - if (arrayHasFromAsyncFunction) return Array.fromAsync(generator); - - const array: T[] = []; - - for await (const element of generator) { - array.push(element); - } - - return array; -}