IO<A>
is a lightweight wrapper around () => Promise<A>
with some useful combinators.
npm install @navidjalali/io
You can make a new IO using one of the following ways:
You can make a successful or failed IO out of a pure value.
IO.succeed(value)
IO.fail(error)
IO.fromNull(maybeNull)
IO.fromUndefined(maybeUndefined)
This is very similar to creating a normal Promise.
new IO<A>((resolve, reject) => {
// ...
})
Any promise can be wrapped into an IO.
IO.fromThunk(() => fetch('/api/v1/posts'))
Exceptions thrown by the function will be lifted into failures.
const unsafeFunction = () => {
// Unsafe code
}
IO.fromThunkSync(unsafeFunction)
Simply call .run()
. This will create a normal Promise.
Any IO that will return some Union type A | InProgress
can be polled using IO.poll
. This will rerun the IO until it succeeds with a result of type A
.
const checkProgress: IO<Result | InProgress> = IO.fromThunk(
() => fetch('/api/v1/progress/poll')
).flatMap(_ => _.json())
const result: IO<Result> = IO.poll(checkProgress, 100)
You can schedule an IO to run later using the scheduleOnce
and scheduleForever
combinators. You can also make more complicated scheduling logic yourself using IO.sleep
and recursion.
You can retry an IO using a RetryPolicy. Currently you can only pick between Spaced
and ExponentialWithBackoff
IO.fromThunk(() => fetch('/api/v1/posts'))
.retry(RetryPolicies.spaced(100, 3))
You can effectively get a rejection if your effect runs longer than a specified period using the timeout
combinator but please keep in mind that this WILL NOT cancel the Promise created from running this effect or interrupt its finalizers. Hopefully I will make this behaviour better soon.
There's more you can do. Feel free to check the code, and contribute if you find a new usecase that can be covered!