diff --git a/src/Lazy/differenceBy.ts b/src/Lazy/differenceBy.ts index da87fe61..58a26dac 100644 --- a/src/Lazy/differenceBy.ts +++ b/src/Lazy/differenceBy.ts @@ -1,3 +1,4 @@ +import { throwIfPromiseError } from "../_internal/error"; import { isAsyncIterable, isIterable } from "../_internal/utils"; import pipe from "../pipe"; import pipe1 from "../pipe1"; @@ -13,7 +14,7 @@ function* sync( iterable1: Iterable, iterable2: Iterable, ) { - const set = new Set(map(f, iterable1)); + const set = new Set(map((a) => throwIfPromiseError(f(a)), iterable1)); yield* pipe( iterable2, diff --git a/src/Lazy/flatMap.ts b/src/Lazy/flatMap.ts index c3000b26..1b1e3e34 100644 --- a/src/Lazy/flatMap.ts +++ b/src/Lazy/flatMap.ts @@ -1,3 +1,4 @@ +import { throwIfPromiseError } from "../_internal/error"; import { isAsyncIterable, isIterable } from "../_internal/utils"; import type Awaited from "../types/Awaited"; import type { DeepFlat, DeepFlatSync } from "../types/DeepFlat"; @@ -87,12 +88,12 @@ function flatMap< ): ReturnFlatMapType | ((iterable: A) => ReturnFlatMapType) { if (iterable === undefined) { return (iterable: A) => { - return flat(map(f, iterable as any)) as any; + return flatMap(f, iterable) as any; }; } if (isIterable>(iterable)) { - return flat(map(f, iterable as any)) as any; + return flat(map((a) => throwIfPromiseError(f(a)), iterable)) as any; } if (isAsyncIterable>>(iterable)) { diff --git a/src/Lazy/intersectionBy.ts b/src/Lazy/intersectionBy.ts index 91f76b24..1275dbb7 100644 --- a/src/Lazy/intersectionBy.ts +++ b/src/Lazy/intersectionBy.ts @@ -1,3 +1,4 @@ +import { throwIfPromiseError } from "../_internal/error"; import { isAsyncIterable, isIterable } from "../_internal/utils"; import pipe from "../pipe"; import pipe1 from "../pipe1"; @@ -13,7 +14,7 @@ function* sync( iterable1: Iterable, iterable2: Iterable, ) { - const set = new Set(map(f, iterable1)); + const set = new Set(map((a) => throwIfPromiseError(f(a)), iterable1)); yield* pipe( iterable2, diff --git a/src/Lazy/map.ts b/src/Lazy/map.ts index 9cf2cc14..30749182 100644 --- a/src/Lazy/map.ts +++ b/src/Lazy/map.ts @@ -20,14 +20,9 @@ function sync( }; } - const res = f(value); - if (isPromise(res)) { - throw new AsyncFunctionException(); - } - return { done: false, - value: res, + value: f(value), }; }, [Symbol.iterator]() { diff --git a/src/Lazy/zipWith.ts b/src/Lazy/zipWith.ts index 02658e10..5b770d72 100644 --- a/src/Lazy/zipWith.ts +++ b/src/Lazy/zipWith.ts @@ -1,3 +1,4 @@ +import { throwIfPromiseError } from "../_internal/error"; import { isAsyncIterable, isIterable } from "../_internal/utils"; import map from "./map"; import zip from "./zip"; @@ -44,7 +45,10 @@ function zipWith( iterable2: Iterable | AsyncIterable, ): IterableIterator | AsyncIterableIterator { if (isIterable(iterable1) && isIterable(iterable2)) { - return map(([a, b]) => f(a, b), zip(iterable1, iterable2)); + return map( + ([a, b]) => throwIfPromiseError(f(a, b)), + zip(iterable1, iterable2), + ); } if (isIterable(iterable1) && isAsyncIterable(iterable2)) { return map(([a, b]) => f(a, b), zip(iterable1, iterable2)); diff --git a/src/_internal/error.ts b/src/_internal/error.ts index f93d63ac..10b3f820 100644 --- a/src/_internal/error.ts +++ b/src/_internal/error.ts @@ -1,3 +1,5 @@ +import { isPromise } from "./utils"; + export class AsyncFunctionException extends Error { static MESSAGE = `'Iterable' can not used with async function. If you want to deal with async function, see: [toAsync](https://fxts.dev/docs/toAsync)`; @@ -6,3 +8,11 @@ If you want to deal with async function, see: [toAsync](https://fxts.dev/docs/to super(message); } } + +export const throwIfPromiseError = (a: Promise | T): T => { + if (isPromise(a)) { + throw new AsyncFunctionException(); + } + + return a; +}; diff --git a/src/every.ts b/src/every.ts index 32d645b6..6d5859c9 100644 --- a/src/every.ts +++ b/src/every.ts @@ -1,3 +1,4 @@ +import { throwIfPromiseError } from "./_internal/error"; import { isAsyncIterable, isIterable } from "./_internal/utils"; import map from "./Lazy/map"; import takeUntil from "./Lazy/takeUntil"; @@ -56,7 +57,7 @@ function every< if (isIterable>(iterable)) { return pipe( - map(f, iterable), + map((a) => throwIfPromiseError(f(a)), iterable), takeUntil(not), (acc) => reduce( diff --git a/src/some.ts b/src/some.ts index c216db9c..46dfc016 100644 --- a/src/some.ts +++ b/src/some.ts @@ -1,3 +1,4 @@ +import { throwIfPromiseError } from "./_internal/error"; import { isAsyncIterable, isIterable } from "./_internal/utils"; import identity from "./identity"; import map from "./Lazy/map"; @@ -76,7 +77,7 @@ function some< if (isIterable>(iterable)) { return pipe( - map(f, iterable), + map((a) => throwIfPromiseError(f(a)), iterable), takeUntil(identity), (acc) => reduce( diff --git a/test/Lazy/map.spec.ts b/test/Lazy/map.spec.ts index f2ae9f19..eba7d636 100644 --- a/test/Lazy/map.spec.ts +++ b/test/Lazy/map.spec.ts @@ -1,4 +1,3 @@ -import { AsyncFunctionException } from "../../src/_internal/error"; import { fx, map, pipe, range, toArray, toAsync } from "../../src/index"; import { Concurrent } from "../../src/Lazy/concurrent"; import { generatorMock } from "../utils"; @@ -16,11 +15,6 @@ describe("map", function () { expect(acc).toEqual([11, 12, 13, 14, 15]); }); - it("should throw an error when the callback is asynchronous", function () { - const res = () => [...map(add10Async, [1, 2, 3, 4, 5])]; - expect(res).toThrowError(new AsyncFunctionException()); - }); - it("should be able to be used as a curried function in the pipeline", function () { const res = pipe( [1, 2, 3, 4], @@ -92,6 +86,18 @@ describe("map", function () { expect(res).toEqual(["1", "2", "3", "4"]); }); + it("should be able to be used as a promise function", async function () { + const res1 = map(async (a) => a, [1, 2, 3, 4]); + + expect(await Promise.all(res1)).toEqual([1, 2, 3, 4]); + + const res2 = pipe( + [1, 2, 3, 4], + map(async (a) => a), + ); + + expect(await Promise.all(res2)).toEqual([1, 2, 3, 4]); + }); it("should be able to be used as a chaining method in the `fx`", async function () { const res = await fx(toAsync([1, 2, 3, 4])) diff --git a/type-check/Lazy/map.test.ts b/type-check/Lazy/map.test.ts index 093b13ec..70288969 100644 --- a/type-check/Lazy/map.test.ts +++ b/type-check/Lazy/map.test.ts @@ -30,6 +30,12 @@ const res10 = pipe( map(async (a) => a), ); +const res11 = map(async (a) => a, [1, 2, 3, 4]); +const res12 = pipe( + [1, 2, 3, 4], + map(async (a) => a), +); + checks([ check, Test.Pass>(), check, Test.Pass>(), @@ -42,4 +48,7 @@ checks([ check>, Test.Pass>(), check, Test.Pass>(), check, Test.Pass>(), + + check>, Test.Pass>(), + check>, Test.Pass>(), ]);