Skip to content

Commit

Permalink
feat: add fn compostion fns, avg & array reverse fns
Browse files Browse the repository at this point in the history
  • Loading branch information
Thanga-Ganapathy committed Apr 8, 2024
1 parent ab7152e commit 3d6e4d9
Show file tree
Hide file tree
Showing 46 changed files with 1,531 additions and 179 deletions.
5 changes: 5 additions & 0 deletions .changeset/two-mails-listen.md
@@ -0,0 +1,5 @@
---
"@opentf/std": minor
---

Added functions composition related functions, Math avg & Array reverse fns.
1 change: 1 addition & 0 deletions .lintstagedrc.json
@@ -0,0 +1 @@
{ "*.md": "prettier --write" }
34 changes: 31 additions & 3 deletions README.md
Expand Up @@ -24,7 +24,7 @@
- Practical Default Options
- Includes Async Utils
- TypeScript Support
- ESM
- Works with both CJS & ESM

## Installation

Expand Down Expand Up @@ -113,6 +113,24 @@ import { sleep } from "@opentf/std";
await sleep(1000); // Suspends execution for 1 second
```

7. Functions composition using `pipe` & `compose` functions:

```js
import { pipe, compose } from "@opentf/std";

pipe(
1,
(x) => x + 1,
(x) => x * 5,
); //=> 10

compose(
1,
(x) => x + 1,
(x) => x * 5,
); //=> 6
```

## API

### Array
Expand All @@ -133,6 +151,7 @@ await sleep(1000); // Suspends execution for 1 second
- [min](https://js-std.pages.dev/Array/min)
- [move](https://js-std.pages.dev/Array/move)
- [range](https://js-std.pages.dev/Array/range)
- [reverse](https://js-std.pages.dev/Array/reverse)
- [sort](https://js-std.pages.dev/Array/sort)
- [sortBy](https://js-std.pages.dev/Array/sortBy)
- [symDiff](https://js-std.pages.dev/Array/symDiff)
Expand All @@ -142,12 +161,17 @@ await sleep(1000); // Suspends execution for 1 second

## Async

- [aCompose](https://js-std.pages.dev/Async/aCompose)
- [aComposeFn](https://js-std.pages.dev/Async/aComposeFn)
- [aFilter](https://js-std.pages.dev/Async/aFilter)
- [aForEach](https://js-std.pages.dev/Async/aForEach)
- [aMap](https://js-std.pages.dev/Async/aMap)
- [aPipe](https://js-std.pages.dev/Async/aPipe)
- [aPipeFn](https://js-std.pages.dev/Async/aPipeFn)

### Maths

- [avg](https://js-std.pages.dev/Maths/avg)
- [clamp](https://js-std.pages.dev/Maths/clamp)
- [divMod](https://js-std.pages.dev/Maths/divMod)
- [isEven](https://js-std.pages.dev/Maths/isEven)
Expand All @@ -168,8 +192,12 @@ await sleep(1000); // Suspends execution for 1 second

### Function

- [sleep](https://js-std.pages.dev/Timers/sleep)
- [noop](https://js-std.pages.dev/Timers/noop)
- [compose](https://js-std.pages.dev/Function/compose)
- [composeFn](https://js-std.pages.dev/Function/composeFn)
- [noop](https://js-std.pages.dev/Function/noop)
- [pipe](https://js-std.pages.dev/Function/pipe)
- [pipeFn](https://js-std.pages.dev/Function/pipeFn)
- [sleep](https://js-std.pages.dev/Function/sleep)

### Colors

Expand Down
2 changes: 1 addition & 1 deletion apps/docs/package.json
Expand Up @@ -15,7 +15,7 @@
"author": "",
"license": "ISC",
"dependencies": {
"@opentf/react-node-repl": "^0.12.0",
"@opentf/react-node-repl": "^0.14.0",
"next": "^14.1.1",
"next-sitemap": "^4.2.3",
"nextra": "^2.13.4",
Expand Down
1 change: 1 addition & 0 deletions apps/docs/pages/Array/_meta.json
Expand Up @@ -15,6 +15,7 @@
"min": "min",
"move": "move",
"range": "range",
"reverse": "reverse",
"sort": "sort",
"sortBy": "sortBy",
"symDiff": "symDiff",
Expand Down
2 changes: 2 additions & 0 deletions apps/docs/pages/Array/move.mdx
Expand Up @@ -10,6 +10,8 @@ Immutable: This does not mutate the given array.
## Syntax

```ts
import { move } from '@opentf/std';

move(arr: T[], from: number, to: number): T[];
```

Expand Down
46 changes: 46 additions & 0 deletions apps/docs/pages/Array/reverse.mdx
@@ -0,0 +1,46 @@
import { Callout } from "nextra/components";
import REPL from "../../components/REPL";

> Reverses the given list of elements order.
<Callout emoji="" type="info">
Immutable: This does not mutate the given array.
</Callout>

## Syntax

```ts
import { reverse } from '@opentf/std';

reverse<T>(arr: T[] = []): T[]
```

## Examples

```ts
reverse([1, 2, 3]) //=> [3, 2, 1]

reverse([{ a: 1 }, { b: 2 }, { c: 3 }])
//=> [
// {
// c: 3,
// },
// {
// b: 2,
// },
// {
// a: 1,
// },
// ]

reverse('Apple')//=> ['e', 'l', 'p', 'p', 'A']

reverse([1, , 3])//=> [3, undefined, 1]
```

## Try

<REPL code={`const { reverse } = require('@opentf/std');
reverse([1, 2, 3]);
`} />
6 changes: 5 additions & 1 deletion apps/docs/pages/Async/_meta.json
@@ -1,5 +1,9 @@
{
"aCompose": "aCompose",
"aComposeFn": "aComposeFn",
"aFilter": "aFilter",
"aForEach": "aForEach",
"aMap": "aMap"
"aMap": "aMap",
"aPipe": "aPipe",
"aPipeFn": "aPipeFn"
}
68 changes: 68 additions & 0 deletions apps/docs/pages/Async/aCompose.mdx
@@ -0,0 +1,68 @@
import { Callout } from "nextra/components";
import REPL from "../../components/REPL";

> Performs functions composition from right to left asynchronously.
<Callout type="default">
The `compose` function is equivalent to `a(b(c(val)))`.
</Callout>

**Related**

- [compose](/Function/compose)
- [composeFn](/Function/composeFn)
- [aComposeFn](/Async/aComposeFn)
- [pipe](/Function/pipe)
- [pipeFn](/Function/pipeFn)
- [aPipe](/Async/aPipe)
- [aPipeFn](/Async/aPipeFn)

## Syntax

```ts
import { aCompose } from '@opentf/std';

aCompose(
val: unknown,
...fns: Function[]
): Promise<unknown>
```

## Examples

```ts
await aCompose(
1,
(x) => Promise.resolve(x + 1),
(x) => Promise.resolve(x * 5)
); //=> 6
```

## Try

<REPL code={`const { aCompose } = require('@opentf/std');
async function main() {
const out = await aCompose(1,
(x) => Promise.resolve(x + 1),
(x) => Promise.resolve(x \* 5)
);
log(out);
}
main();
`} />

## Learn

Why we need function composition?

- The deep nesting of functions is hard to read.
- It eliminates temporary variables.
- Method chaining is limited, for Eg: await, yeild, etc.

### Resources

- [tc39/proposal-pipeline-operator](https://github.com/tc39/proposal-pipeline-operator)

- [Hack Pipe Operator](https://docs.hhvm.com/hack/expressions-and-operators/pipe)
64 changes: 64 additions & 0 deletions apps/docs/pages/Async/aComposeFn.mdx
@@ -0,0 +1,64 @@
import { Callout } from "nextra/components";
import REPL from "../../components/REPL";

> Returns a function that performs functions composition from right to left asynchronously.
<Callout type="default">
The `compose` function is equivalent to `a(b(c(val)))`.
</Callout>

**Related**

- [compose](/Function/compose)
- [composeFn](/Function/composeFn)
- [aCompose](/Async/aCompose)
- [pipe](/Function/pipe)
- [pipeFn](/Function/pipeFn)
- [aPipe](/Async/aPipe)
- [aPipeFn](/Async/aPipeFn)

## Syntax

```ts
import { aComposeFn } from '@opentf/std';

aComposeFn(
...fns: Function[]
): (...args: unknown[]) => unknown
```

## Examples

```ts
const transform = aComposeFn((x) => Promise.resolve(Math.ceil(x)), Math.pow);
await transform(1.5, 2.5); //=> 3
```

## Try

<REPL code={`const { aComposeFn } = require('@opentf/std');
async function main() {
const transform = aComposeFn(
(x) => Promise.resolve(Math.ceil(x)),
Math.pow
);
log(await transform(1.5, 2.5));
}
main();
`} />

## Learn

Why we need function composition?

- The deep nesting of functions is hard to read.
- It eliminates temporary variables.
- Method chaining is limited, for Eg: await, yeild, etc.

### Resources

- [tc39/proposal-pipeline-operator](https://github.com/tc39/proposal-pipeline-operator)

- [Hack Pipe Operator](https://docs.hhvm.com/hack/expressions-and-operators/pipe)
68 changes: 68 additions & 0 deletions apps/docs/pages/Async/aPipe.mdx
@@ -0,0 +1,68 @@
import { Callout } from "nextra/components";
import REPL from "../../components/REPL";

> Performs functions composition from left to right asynchronously.
<Callout type="default">
The `pipe` function is equivalent to `c(b(a(val)))`.
</Callout>

**Related**

- [pipe](/Function/pipe)
- [pipeFn](/Function/pipeFn)
- [aPipeFn](/Async/aPipeFn)
- [compose](/Function/compose)
- [composeFn](/Function/composeFn)
- [aCompose](/Async/aCompose)
- [aComposeFn](/Async/aComposeFn)

## Syntax

```ts
import { aPipe } from '@opentf/std';

aPipe(
val: unknown,
...fns: Function[]
): Promise<unknown>
```

## Examples

```ts
await aPipe(
"guest",
(s) => capitalize(s),
(x) => Promise.resolve(`Welcome ${x}`)
); //=> 'Welcome Guest'
```

## Try

<REPL code={`const { aPipe, capitalize } = require('@opentf/std');
async function main() {
const out = await aPipe('guest',
(s) => capitalize(s),
(x) => Promise.resolve(\`Welcome \${x}\`)
);
log(out);
}
main();
`} />

## Learn

Why we need function composition?

- The deep nesting of functions is hard to read.
- It eliminates temporary variables.
- Method chaining is limited, for Eg: await, yeild, etc.

### Resources

- [tc39/proposal-pipeline-operator](https://github.com/tc39/proposal-pipeline-operator)

- [Hack Pipe Operator](https://docs.hhvm.com/hack/expressions-and-operators/pipe)

0 comments on commit 3d6e4d9

Please sign in to comment.