Skip to content

Commit

Permalink
feat(website): a bunch more docs updates (#54)
Browse files Browse the repository at this point in the history
  • Loading branch information
TomerAberbach authored Nov 29, 2024
1 parent 7c8ad5b commit 38f6ca9
Show file tree
Hide file tree
Showing 9 changed files with 452 additions and 224 deletions.
16 changes: 16 additions & 0 deletions website/docs/concepts/concurrent-iterable.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ const createConcurIterable = () =>
console.time(`concur iterable iteration`)
await forEachConcur(unused => console.log(`Iterated!`), createConcurIterable())
console.timeEnd(`concur iterable iteration`)
//=> Iterated!
//=> Iterated!
//=> Iterated!
//=> Iterated!
// NOTE: This duration may vary slightly between runs
//=> concur iterable iteration: 100 ms

async function* createAsyncIterable() {
yield delay(100)
Expand All @@ -58,6 +64,12 @@ for await (const unused of createAsyncIterable()) {
console.log(`Iterated!`)
}
console.timeEnd(`async iterable iteration`)
//=> Iterated!
//=> Iterated!
//=> Iterated!
//=> Iterated!
// NOTE: This duration may vary slightly between runs
//=> async iterable iteration: 300 ms
```

Iterating over the concur iterable takes just 100 milliseconds while iterating
Expand Down Expand Up @@ -156,11 +168,15 @@ const withLfi = await pipe(
reduceConcur(toArray()),
)
console.timeEnd(`with lfi`)
// NOTE: This duration may vary slightly between runs
//=> with lfi: 6011 ms

// Takes 10 seconds! The first item is a bottleneck because `p-map` waits for all callbacks
console.time(`without lfi`)
const withoutLfi = await pFilter(await pMap([0, 1, 2], mapFn), filterFn)
console.timeEnd(`without lfi`)
// NOTE: This duration may vary slightly between runs
//=> without lfi: 10000 ms
```

:::note
Expand Down
12 changes: 11 additions & 1 deletion website/docs/concepts/currying.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import {
toMap,
toSet,
} from 'lfi'
import zoo from 'zoo'
import zoo from 'lfi:zoo'

const getSlothNamesByAgeWithCurrying = () =>
pipe(
Expand All @@ -64,6 +64,11 @@ const getSlothNamesByAgeWithCurrying = () =>
reduce(toGrouped(toSet(), toMap())),
)
console.log(getSlothNamesByAgeWithCurrying())
//=> Map(3) {
//=> 7 => Set(2) { 'strawberry', 'bitsy' },
//=> 19 => Set(1) { 'max' },
//=> 24 => Set(1) { 'tommy' }
//=> }

const getSlothNamesByAgeWithoutCurrying = () =>
reduce(
Expand All @@ -77,6 +82,11 @@ const getSlothNamesByAgeWithoutCurrying = () =>
),
)
console.log(getSlothNamesByAgeWithoutCurrying())
//=> Map(3) {
//=> 7 => Set(2) { 'strawberry', 'bitsy' },
//=> 19 => Set(1) { 'max' },
//=> 24 => Set(1) { 'tommy' }
//=> }
```

`getSlothNamesByAgeWithCurrying` is easier to read because the operation order
Expand Down
172 changes: 106 additions & 66 deletions website/docs/concepts/optional.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -43,23 +43,23 @@ For example, consider the following code:
```js playground
import { find, or, pipe } from 'lfi'

const getAnimal = targetAnimal =>
const findWordContaining = string =>
pipe(
[`dog`, `cat`, `bunny`],
// Return an optional potentially containing the found animal
find(animal => animal === targetAnimal),
[`sloth`, `lazy`, `sleep`],
// Return an optional potentially containing the found word
find(word => word.includes(string)),
// Return the optional's value if it exists, or the result of the callback otherwise
or(() => `no ${targetAnimal}???`),
or(() => `no ${string}???`),
)

console.log(getAnimal(`dog`))
//=> dog
console.log(getAnimal(`cat`))
//=> cat
console.log(getAnimal(`bunny`))
//=> bunny
console.log(getAnimal(`sloth`))
//=> no sloth???
console.log(findWordContaining(`lot`))
//=> sloth
console.log(findWordContaining(`la`))
//=> lazy
console.log(findWordContaining(`ep`))
//=> sleep
console.log(findWordContaining(`lfi`))
//=> no lfi???
```

</TabItem>
Expand All @@ -68,24 +68,30 @@ console.log(getAnimal(`sloth`))
```js playground
import { asAsync, findAsync, orAsync, pipe } from 'lfi'

const getAnimal = targetAnimal =>
const API_URL = `https://api.dictionaryapi.dev/api/v2/entries/en`

const findWordWithPartOfSpeech = partOfSpeech =>
pipe(
asAsync([`dog`, `cat`, `bunny`]),
// Return an async optional potentially containing the found animal
findAsync(animal => animal === targetAnimal),
asAsync([`sloth`, `lazy`, `sleep`]),
// Return an async optional potentially containing the found word
findAsync(async word => {
const response = await fetch(`${API_URL}/${word}`)
const [{ meanings }] = await response.json()
return meanings.some(meaning => meaning.partOfSpeech === partOfSpeech)
}),
// Return a promise that resolves to the async optional's value if it
// exists, or the result of the callback otherwise
orAsync(() => `no ${targetAnimal}???`),
orAsync(() => `no ${partOfSpeech}???`),
)

console.log(await getAnimal(`dog`))
//=> dog
console.log(await getAnimal(`cat`))
//=> cat
console.log(await getAnimal(`bunny`))
//=> bunny
console.log(await getAnimal(`sloth`))
//=> no sloth???
console.log(await findWordWithPartOfSpeech(`noun`))
//=> sloth
console.log(await findWordWithPartOfSpeech(`verb`))
//=> sloth
console.log(await findWordWithPartOfSpeech(`adjective`))
//=> lazy
console.log(await findWordWithPartOfSpeech(`adverb`))
//=> no adverb???
```

</TabItem>
Expand All @@ -94,24 +100,32 @@ console.log(await getAnimal(`sloth`))
```js playground
import { asConcur, findConcur, orConcur, pipe } from 'lfi'

const getAnimal = targetAnimal =>
const API_URL = `https://api.dictionaryapi.dev/api/v2/entries/en`

const findWordWithPartOfSpeech = partOfSpeech =>
pipe(
asConcur([`dog`, `cat`, `bunny`]),
// Return a concur optional potentially containing the found animal
findConcur(animal => animal === targetAnimal),
asConcur([`sloth`, `lazy`, `sleep`]),
// Return an concur optional potentially containing the found word
findConcur(async word => {
const response = await fetch(`${API_URL}/${word}`)
const [{ meanings }] = await response.json()
return meanings.some(meaning => meaning.partOfSpeech === partOfSpeech)
}),
// Return a promise that resolves to the concur optional's value if it
// exists, or the result of the callback otherwise
orConcur(() => `no ${targetAnimal}???`),
orConcur(() => `no ${partOfSpeech}???`),
)

console.log(await getAnimal(`dog`))
//=> dog
console.log(await getAnimal(`cat`))
//=> cat
console.log(await getAnimal(`bunny`))
//=> bunny
console.log(await getAnimal(`sloth`))
//=> no sloth???
console.log(await findWordWithPartOfSpeech(`noun`))
// NOTE: This word may change between runs
//=> sloth
console.log(await findWordWithPartOfSpeech(`verb`))
// NOTE: This word may change between runs
//=> sloth
console.log(await findWordWithPartOfSpeech(`adjective`))
//=> lazy
console.log(await findWordWithPartOfSpeech(`adverb`))
//=> no adverb???
```

</TabItem>
Expand All @@ -134,19 +148,23 @@ For example, consider the following code:
```js playground
import { find, map, or, pipe } from 'lfi'

const getAnimal = targetAnimal =>
const findWordContaining = string =>
pipe(
[`dog`, `cat`, `bunny`],
find(animal => animal === targetAnimal),
[`sloth`, `lazy`, `sleep`],
find(word => word.includes(string)),
// This works on the optional because it's just an iterable
map(animal => animal.toUpperCase()),
or(() => `no ${targetAnimal}???`),
map(word => word.toUpperCase()),
or(() => `no ${string}???`),
)

console.log(getAnimal(`dog`))
console.log(getAnimal(`cat`))
console.log(getAnimal(`bunny`))
console.log(getAnimal(`sloth`))
console.log(findWordContaining(`lot`))
//=> SLOTH
console.log(findWordContaining(`la`))
//=> LAZY
console.log(findWordContaining(`ep`))
//=> SLEEP
console.log(findWordContaining(`lfi`))
//=> no lfi???
```

We were trivially able to use our existing `map` logic on the optional value!
Expand All @@ -157,19 +175,29 @@ We were trivially able to use our existing `map` logic on the optional value!
```js playground
import { asAsync, findAsync, mapAsync, orAsync, pipe } from 'lfi'

const getAnimal = targetAnimal =>
const API_URL = `https://api.dictionaryapi.dev/api/v2/entries/en`

const findWordWithPartOfSpeech = partOfSpeech =>
pipe(
asAsync([`dog`, `cat`, `bunny`]),
findAsync(animal => animal === targetAnimal),
asAsync([`sloth`, `lazy`, `sleep`]),
findAsync(async word => {
const response = await fetch(`${API_URL}/${word}`)
const [{ meanings }] = await response.json()
return meanings.some(meaning => meaning.partOfSpeech === partOfSpeech)
}),
// This works on the async optional because it's just an async iterable
mapAsync(animal => animal.toUpperCase()),
orAsync(() => `no ${targetAnimal}???`),
mapAsync(word => word.toUpperCase()),
orAsync(() => `no ${partOfSpeech}???`),
)

console.log(await getAnimal(`dog`))
console.log(await getAnimal(`cat`))
console.log(await getAnimal(`bunny`))
console.log(await getAnimal(`sloth`))
console.log(await findWordWithPartOfSpeech(`noun`))
//=> SLOTH
console.log(await findWordWithPartOfSpeech(`verb`))
//=> SLOTH
console.log(await findWordWithPartOfSpeech(`adjective`))
//=> LAZY
console.log(await findWordWithPartOfSpeech(`adverb`))
//=> no adverb???
```

We were trivially able to use our existing `mapAsync` logic on the async
Expand All @@ -181,19 +209,31 @@ optional value!
```js playground
import { asConcur, findConcur, mapConcur, orConcur, pipe } from 'lfi'

const getAnimal = targetAnimal =>
const API_URL = `https://api.dictionaryapi.dev/api/v2/entries/en`

const findWordWithPartOfSpeech = partOfSpeech =>
pipe(
asConcur([`dog`, `cat`, `bunny`]),
findConcur(animal => animal === targetAnimal),
asConcur([`sloth`, `lazy`, `sleep`]),
findConcur(async word => {
const response = await fetch(`${API_URL}/${word}`)
const [{ meanings }] = await response.json()
return meanings.some(meaning => meaning.partOfSpeech === partOfSpeech)
}),
// This works on the concur optional because it's just an concur iterable
mapConcur(animal => animal.toUpperCase()),
orConcur(() => `no ${targetAnimal}???`),
mapConcur(word => word.toUpperCase()),
orConcur(() => `no ${partOfSpeech}???`),
)

console.log(await getAnimal(`dog`))
console.log(await getAnimal(`cat`))
console.log(await getAnimal(`bunny`))
console.log(await getAnimal(`sloth`))
console.log(await findWordWithPartOfSpeech(`noun`))
// NOTE: This word may change between runs
//=> SLOTH
console.log(await findWordWithPartOfSpeech(`verb`))
// NOTE: This word may change between runs
//=> SLOTH
console.log(await findWordWithPartOfSpeech(`adjective`))
//=> LAZY
console.log(await findWordWithPartOfSpeech(`adverb`))
//=> no adverb???
```

We were trivially able to use our existing `mapConcur` logic on the concur
Expand Down
Loading

0 comments on commit 38f6ca9

Please sign in to comment.