Skip to content

Commit

Permalink
Merge pull request #7 from jsr-core/compose
Browse files Browse the repository at this point in the history
feat: Add `compose` function for composing multiple operators
  • Loading branch information
lambdalisue authored Oct 27, 2024
2 parents fdee976 + 2936dc6 commit 66551b7
Show file tree
Hide file tree
Showing 17 changed files with 2,294 additions and 978 deletions.
4 changes: 3 additions & 1 deletion .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# These are supported funding model platforms

github: [lambdalisue] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
github: [
lambdalisue,
] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
Expand Down
63 changes: 61 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ inference and type checking of the operator functions.
Pipe a value through a series of operator functions.

```ts
import { pipe } from "@core/pipe";
import { pipe } from "@core/pipe/pipe";

const result = pipe(
1,
Expand All @@ -36,7 +36,7 @@ Or use `async` module to pipe a value through a series of asynchronous operator
functions.

```ts
import { pipe } from "@core/pipe/async";
import { pipe } from "@core/pipe/async/pipe";

const result = await pipe(
1,
Expand All @@ -47,6 +47,65 @@ const result = await pipe(
console.log(result); // "4"
```

If you want to create a new function that composes multiple operators, use
`compose` like below.

```ts
import { compose } from "@core/pipe/compose";

const operator = compose(
(v: number) => v + 1, // The first operator must be typed explicitly
(v) => v * 2, // inferred as (v: number) => number
(v) => v.toString(), // inferred as (v: number) => string
);
console.log(operator(1)); // "4"
```

Or use `async` module to compose multiple asynchronous operators.

```ts
import { compose } from "@core/pipe/async/compose";

const operator = compose(
(v: number) => Promise.resolve(v + 1), // The first operator must be typed explicitly
(v) => Promise.resolve(v * 2), // inferred as (v: number) => number | Promise<number>
(v) => Promise.resolve(v.toString()), // inferred as (v: number) => string | Promise<string>
);
console.log(await operator(1)); // "4"
```

## Difference

The `pipe` function in the root module is equivalent to function calls without
`await` like below.

```ts
import { pipe } from "@core/pipe/pipe";

const a = (v: unknown) => v;
const b = (v: unknown) => v;
const c = (v: unknown) => v;

// Equivalent
console.log(pipe(1, a, b, c)); // 1
console.log(c(b(a(1)))); // 1
```

The `pipe` function in the `async` module is equivalent to function calls with
`await` like below.

```ts
import { pipe } from "@core/pipe/async/pipe";

const a = (v: unknown) => Promise.resolve(v);
const b = (v: unknown) => Promise.resolve(v);
const c = (v: unknown) => Promise.resolve(v);

// Equivalent
console.log(await pipe(1, a, b, c)); // 1
console.log(await c(await b(await a(1)))); // 1
```

## License

The code follows MIT license written in [LICENSE](./LICENSE). Contributors need
Expand Down
8 changes: 8 additions & 0 deletions _common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { Operator } from "./operator.ts";

/**
* @internal
*/
export type LastOperatorReturn<T extends Operator<unknown, unknown>[]> =
T extends [...Operator<unknown, unknown>[], Operator<unknown, infer R>] ? R
: never;
10 changes: 10 additions & 0 deletions async/_common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { AsyncOperator } from "./operator.ts";

/**
* @internal
*/
export type LastAsyncOperatorReturn<
T extends AsyncOperator<unknown, unknown>[],
> = T extends
[...AsyncOperator<unknown, unknown>[], AsyncOperator<unknown, infer R>] ? R
: never;
Loading

0 comments on commit 66551b7

Please sign in to comment.