Skip to content

Commit

Permalink
Merge pull request #14 from jsr-core/pipe
Browse files Browse the repository at this point in the history
feat: support `@core/pipe` package
  • Loading branch information
lambdalisue authored Aug 12, 2024
2 parents 20b888b + f3fa384 commit 14868c7
Show file tree
Hide file tree
Showing 108 changed files with 3,180 additions and 3 deletions.
665 changes: 662 additions & 3 deletions README.md

Large diffs are not rendered by default.

40 changes: 40 additions & 0 deletions README_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { assertEquals } from "@std/assert";
import { pipe } from "@core/pipe";
import * as rootMod from "@core/iterutil";
import * as asyncMod from "@core/iterutil/async";
import * as pipeMod from "@core/iterutil/pipe";
import * as pipeAsyncMod from "@core/iterutil/pipe/async";

Deno.test("README", async (t) => {
await t.step("case 1", () => {
const iter = rootMod.map([1, 2, 3], (v) => v * 2);
assertEquals(Array.from(iter), [2, 4, 6]);
});

await t.step("case 2", async () => {
const iter = asyncMod.map([1, 2, 3], (v) => Promise.resolve(v * 2));
assertEquals(await Array.fromAsync(iter), [2, 4, 6]);
});

await t.step("case 3", () => {
const iter = pipe(
[1, 2, 3],
pipeMod.map((v) => v * 2),
pipeMod.cycle,
pipeMod.take(10),
pipeMod.filter((v) => v % 2 === 0),
);
assertEquals(Array.from(iter), [2, 4, 6, 2, 4, 6, 2, 4, 6, 2]);
});

await t.step("case 4", async () => {
const iter = pipe(
[1, 2, 3],
pipeAsyncMod.map((v) => v * 2),
pipeAsyncMod.cycle,
pipeAsyncMod.take(10),
pipeAsyncMod.filter((v) => v % 2 === 0),
);
assertEquals(await Array.fromAsync(iter), [2, 4, 6, 2, 4, 6, 2, 4, 6, 2]);
});
});
2 changes: 2 additions & 0 deletions async/uniq.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/**
* Returns an iterable that yields the unique elements of the input iterable.
*
* Use {@linkcode https://jsr.io/@core/iterutil/doc/uniq/~/uniq uniq} to get the unique elements synchronously.
*
* @param iterable The iterable to get the unique elements of.
* @param identify An optional function to transform the elements before checking for uniqueness.
* @returns An iterable that yields the unique elements of the input iterable.
Expand Down
109 changes: 109 additions & 0 deletions deno.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,58 @@
"./map": "./map.ts",
"./pairwise": "./pairwise.ts",
"./partition": "./partition.ts",
"./pipe": "./pipe/mod.ts",
"./pipe/async": "./pipe/async/mod.ts",
"./pipe/async/chain": "./pipe/async/chain.ts",
"./pipe/async/chunked": "./pipe/async/chunked.ts",
"./pipe/async/compact": "./pipe/async/compact.ts",
"./pipe/async/compress": "./pipe/async/compress.ts",
"./pipe/async/cycle": "./pipe/async/cycle.ts",
"./pipe/async/drop": "./pipe/async/drop.ts",
"./pipe/async/drop-while": "./pipe/async/drop_while.ts",
"./pipe/async/enumerate": "./pipe/async/enumerate.ts",
"./pipe/async/every": "./pipe/async/every.ts",
"./pipe/async/filter": "./pipe/async/filter.ts",
"./pipe/async/find": "./pipe/async/find.ts",
"./pipe/async/first": "./pipe/async/first.ts",
"./pipe/async/flat-map": "./pipe/async/flat_map.ts",
"./pipe/async/flatten": "./pipe/async/flatten.ts",
"./pipe/async/for-each": "./pipe/async/for_each.ts",
"./pipe/async/last": "./pipe/async/last.ts",
"./pipe/async/map": "./pipe/async/map.ts",
"./pipe/async/pairwise": "./pipe/async/pairwise.ts",
"./pipe/async/partition": "./pipe/async/partition.ts",
"./pipe/async/reduce": "./pipe/async/reduce.ts",
"./pipe/async/some": "./pipe/async/some.ts",
"./pipe/async/take": "./pipe/async/take.ts",
"./pipe/async/take-while": "./pipe/async/take_while.ts",
"./pipe/async/uniq": "./pipe/async/uniq.ts",
"./pipe/async/zip": "./pipe/async/zip.ts",
"./pipe/chain": "./pipe/chain.ts",
"./pipe/chunked": "./pipe/chunked.ts",
"./pipe/compact": "./pipe/compact.ts",
"./pipe/compress": "./pipe/compress.ts",
"./pipe/cycle": "./pipe/cycle.ts",
"./pipe/drop": "./pipe/drop.ts",
"./pipe/drop-while": "./pipe/drop_while.ts",
"./pipe/enumerate": "./pipe/enumerate.ts",
"./pipe/every": "./pipe/every.ts",
"./pipe/filter": "./pipe/filter.ts",
"./pipe/find": "./pipe/find.ts",
"./pipe/first": "./pipe/first.ts",
"./pipe/flat-map": "./pipe/flat_map.ts",
"./pipe/flatten": "./pipe/flatten.ts",
"./pipe/for-each": "./pipe/for_each.ts",
"./pipe/last": "./pipe/last.ts",
"./pipe/map": "./pipe/map.ts",
"./pipe/pairwise": "./pipe/pairwise.ts",
"./pipe/partition": "./pipe/partition.ts",
"./pipe/reduce": "./pipe/reduce.ts",
"./pipe/some": "./pipe/some.ts",
"./pipe/take": "./pipe/take.ts",
"./pipe/take-while": "./pipe/take_while.ts",
"./pipe/uniq": "./pipe/uniq.ts",
"./pipe/zip": "./pipe/zip.ts",
"./range": "./range.ts",
"./reduce": "./reduce.ts",
"./some": "./some.ts",
Expand Down Expand Up @@ -126,13 +178,70 @@
"@core/iterutil/map": "./map.ts",
"@core/iterutil/pairwise": "./pairwise.ts",
"@core/iterutil/partition": "./partition.ts",
"@core/iterutil/pipe": "./pipe/mod.ts",
"@core/iterutil/pipe/async": "./pipe/async/mod.ts",
"@core/iterutil/pipe/async/chain": "./pipe/async/chain.ts",
"@core/iterutil/pipe/async/chunked": "./pipe/async/chunked.ts",
"@core/iterutil/pipe/async/compact": "./pipe/async/compact.ts",
"@core/iterutil/pipe/async/compress": "./pipe/async/compress.ts",
"@core/iterutil/pipe/async/count": "./pipe/async/count.ts",
"@core/iterutil/pipe/async/cycle": "./pipe/async/cycle.ts",
"@core/iterutil/pipe/async/drop": "./pipe/async/drop.ts",
"@core/iterutil/pipe/async/drop-while": "./pipe/async/drop_while.ts",
"@core/iterutil/pipe/async/enumerate": "./pipe/async/enumerate.ts",
"@core/iterutil/pipe/async/every": "./pipe/async/every.ts",
"@core/iterutil/pipe/async/filter": "./pipe/async/filter.ts",
"@core/iterutil/pipe/async/find": "./pipe/async/find.ts",
"@core/iterutil/pipe/async/first": "./pipe/async/first.ts",
"@core/iterutil/pipe/async/flat-map": "./pipe/async/flat_map.ts",
"@core/iterutil/pipe/async/flatten": "./pipe/async/flatten.ts",
"@core/iterutil/pipe/async/for-each": "./pipe/async/for_each.ts",
"@core/iterutil/pipe/async/iter": "./pipe/async/iter.ts",
"@core/iterutil/pipe/async/last": "./pipe/async/last.ts",
"@core/iterutil/pipe/async/map": "./pipe/async/map.ts",
"@core/iterutil/pipe/async/pairwise": "./pipe/async/pairwise.ts",
"@core/iterutil/pipe/async/partition": "./pipe/async/partition.ts",
"@core/iterutil/pipe/async/reduce": "./pipe/async/reduce.ts",
"@core/iterutil/pipe/async/some": "./pipe/async/some.ts",
"@core/iterutil/pipe/async/take": "./pipe/async/take.ts",
"@core/iterutil/pipe/async/take-while": "./pipe/async/take_while.ts",
"@core/iterutil/pipe/async/uniq": "./pipe/async/uniq.ts",
"@core/iterutil/pipe/async/zip": "./pipe/async/zip.ts",
"@core/iterutil/pipe/chain": "./pipe/chain.ts",
"@core/iterutil/pipe/chunked": "./pipe/chunked.ts",
"@core/iterutil/pipe/compact": "./pipe/compact.ts",
"@core/iterutil/pipe/compress": "./pipe/compress.ts",
"@core/iterutil/pipe/count": "./pipe/count.ts",
"@core/iterutil/pipe/cycle": "./pipe/cycle.ts",
"@core/iterutil/pipe/drop": "./pipe/drop.ts",
"@core/iterutil/pipe/drop-while": "./pipe/drop_while.ts",
"@core/iterutil/pipe/enumerate": "./pipe/enumerate.ts",
"@core/iterutil/pipe/every": "./pipe/every.ts",
"@core/iterutil/pipe/filter": "./pipe/filter.ts",
"@core/iterutil/pipe/find": "./pipe/find.ts",
"@core/iterutil/pipe/first": "./pipe/first.ts",
"@core/iterutil/pipe/flat-map": "./pipe/flat_map.ts",
"@core/iterutil/pipe/flatten": "./pipe/flatten.ts",
"@core/iterutil/pipe/for-each": "./pipe/for_each.ts",
"@core/iterutil/pipe/iter": "./pipe/iter.ts",
"@core/iterutil/pipe/last": "./pipe/last.ts",
"@core/iterutil/pipe/map": "./pipe/map.ts",
"@core/iterutil/pipe/pairwise": "./pipe/pairwise.ts",
"@core/iterutil/pipe/partition": "./pipe/partition.ts",
"@core/iterutil/pipe/reduce": "./pipe/reduce.ts",
"@core/iterutil/pipe/some": "./pipe/some.ts",
"@core/iterutil/pipe/take": "./pipe/take.ts",
"@core/iterutil/pipe/take-while": "./pipe/take_while.ts",
"@core/iterutil/pipe/uniq": "./pipe/uniq.ts",
"@core/iterutil/pipe/zip": "./pipe/zip.ts",
"@core/iterutil/range": "./range.ts",
"@core/iterutil/reduce": "./reduce.ts",
"@core/iterutil/some": "./some.ts",
"@core/iterutil/take": "./take.ts",
"@core/iterutil/take-while": "./take_while.ts",
"@core/iterutil/uniq": "./uniq.ts",
"@core/iterutil/zip": "./zip.ts",
"@core/pipe": "jsr:@core/pipe@^0.2.0",
"@core/unknownutil": "jsr:@core/unknownutil@^4.0.1",
"@std/assert": "jsr:@std/assert@^1.0.2",
"@std/jsonc": "jsr:@std/jsonc@^1.0.0",
Expand Down
35 changes: 35 additions & 0 deletions pipe/async/chain.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { type Chain, chain as base } from "@core/iterutil/async/chain";

/**
* Returns an operator that chains multiple iterables to the iterable.
*
* See {@linkcode https://jsr.io/@core/iterutil/doc/async/chain/~/chain chain} for native chain.
*
* @param iterables The iterables to chain to the iterable.
* @returns An operator that chains multiple iterables to the iterable.
*
* @example
* ```ts
* import { pipe } from "@core/pipe";
* import { chain } from "@core/iterutil/pipe/async/chain";
*
* const iter = pipe(
* [1, 2, 3],
* chain(["a", "b"], [true]),
* );
* console.log(await Array.fromAsync(iter)); // [1, 2, 3, "a", "b", true]
* ```
*/
export function chain<
U extends readonly [
Iterable<unknown> | AsyncIterable<unknown>,
...(Iterable<unknown> | AsyncIterable<unknown>)[],
],
>(
...iterables: U
): <T>(
iterable: Iterable<T> | AsyncIterable<T>,
) => AsyncIterable<T | Chain<U>> {
return <T>(iterable: Iterable<T> | AsyncIterable<T>) =>
base(iterable, ...iterables) as AsyncIterable<T | Chain<U>>;
}
20 changes: 20 additions & 0 deletions pipe/async/chain_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { assertEquals } from "@std/assert";
import { assertType, type IsExact } from "@std/testing/types";
import { pipe } from "@core/pipe";
import { chain } from "./chain.ts";

Deno.test("chain", async (t) => {
await t.step("usage", async () => {
const result = pipe(
[1, 2, 3],
chain(["a", "b"], [true]),
);
const expected = [1, 2, 3, "a", "b", true];
assertEquals(await Array.fromAsync(result), expected);
assertType<
IsExact<typeof result, AsyncIterable<number | string | boolean>>
>(
true,
);
});
});
27 changes: 27 additions & 0 deletions pipe/async/chunked.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { chunked as base } from "@core/iterutil/async/chunked";

/**
* Returns an operator that chunks the iterable into arrays of `size`.
*
* See {@linkcode https://jsr.io/@core/iterutil/doc/async/chunked/~/chunked chunked} for native chunked.
*
* @param size The size of each chunk.
* @return An operator that chunks the iterable into arrays of `size`.
*
* @example
* ```ts
* import { pipe } from "@core/pipe";
* import { chunked } from "@core/iterutil/pipe/async/chunked";
*
* const iter = pipe(
* [1, 2, 3, 4, 5],
* chunked(2),
* );
* console.log(await Array.fromAsync(iter)); // [[1, 2], [3, 4], [5]]
* ```
*/
export function chunked(
size: number,
): <T>(iterable: Iterable<T> | AsyncIterable<T>) => AsyncIterable<T[]> {
return (iterable) => base(iterable, size);
}
13 changes: 13 additions & 0 deletions pipe/async/chunked_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { assertEquals } from "@std/assert";
import { assertType, type IsExact } from "@std/testing/types";
import { pipe } from "@core/pipe";
import { chunked } from "./chunked.ts";

Deno.test("chunked", async (t) => {
await t.step("usage", async () => {
const result = pipe([1, 2, 3, 4, 5, 6], chunked(2));
const expected = [[1, 2], [3, 4], [5, 6]];
assertEquals(await Array.fromAsync(result), expected);
assertType<IsExact<typeof result, AsyncIterable<number[]>>>(true);
});
});
22 changes: 22 additions & 0 deletions pipe/async/compact.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { compact } from "@core/iterutil/async/compact";

export {
/**
* An operator to remove all nullish (`null` or `undefined`) values from an iterable.
*
* See {@linkcode https://jsr.io/@core/iterutil/doc/async/compact/~/compact compact} for native compact.
*
* @example
* ```ts
* import { pipe } from "@core/pipe";
* import { compact } from "@core/iterutil/pipe/async/compact";
*
* const iter = pipe(
* [1, undefined, 2, null, 3],
* compact,
* );
* console.log(await Array.fromAsync(iter)); // [1, 2, 3]
* ```
*/
compact,
};
13 changes: 13 additions & 0 deletions pipe/async/compact_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { assertEquals } from "@std/assert";
import { assertType, type IsExact } from "@std/testing/types";
import { pipe } from "@core/pipe";
import { compact } from "./compact.ts";

Deno.test("compact", async (t) => {
await t.step("usage", async () => {
const result = pipe([1, undefined, 2, null, 3], compact);
const expected = [1, 2, 3];
assertEquals(await Array.fromAsync(result), expected);
assertType<IsExact<typeof result, AsyncIterable<number>>>(true);
});
});
27 changes: 27 additions & 0 deletions pipe/async/compress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { compress as base } from "@core/iterutil/async/compress";

/**
* Returns an operator that compresses an iterable by selecting elements using a selector iterable.
*
* See {@linkcode https://jsr.io/@core/iterutil/doc/async/compress/~/compress compress} for native compress.
*
* @param selectors The selectors to use.
* @returns An operator that compresses an iterable by selecting elements using a selector iterable.
*
* @example
* ```ts
* import { pipe } from "@core/pipe";
* import { compress } from "@core/iterutil/pipe/async/compress";
*
* const iter = pipe(
* [1, 2, 3, 4, 5],
* compress([true, false, true, false, true]),
* );
* console.log(await Array.fromAsync(iter)); // [1, 3, 5]
* ```
*/
export function compress(
selectors: Iterable<boolean> | AsyncIterable<boolean>,
): <T>(iterable: Iterable<T> | AsyncIterable<T>) => AsyncIterable<T> {
return (iterable) => base(iterable, selectors);
}
16 changes: 16 additions & 0 deletions pipe/async/compress_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { assertEquals } from "@std/assert";
import { assertType, type IsExact } from "@std/testing/types";
import { pipe } from "@core/pipe";
import { compress } from "./compress.ts";

Deno.test("compress", async (t) => {
await t.step("usage", async () => {
const result = pipe(
[1, 2, 3, 4, 5],
compress([true, false, true, false, true]),
);
const expected = [1, 3, 5];
assertEquals(await Array.fromAsync(result), expected);
assertType<IsExact<typeof result, AsyncIterable<number>>>(true);
});
});
24 changes: 24 additions & 0 deletions pipe/async/cycle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { cycle } from "@core/iterutil/async/cycle";

export {
/**
* An operator to return a function that cycles the elements of an iterable.
*
* See {@linkcode https://jsr.io/@core/iterutil/doc/async/cycle/~/cycle cycle} for native cycle.
*
* @example
* ```ts
* import { pipe } from "@core/pipe";
* import { cycle } from "@core/iterutil/pipe/async/cycle";
* import { take } from "@core/iterutil/pipe/async/take";
*
* const iter = pipe(
* [1, 2, 3],
* cycle,
* take(5),
* );
* console.log(await Array.fromAsync(iter)); // [1, 2, 3, 1, 2]
* ```
*/
cycle,
};
Loading

0 comments on commit 14868c7

Please sign in to comment.