import { EitherAsync } from 'purify-ts/EitherAsync'
function validateRequest(req: Request): Either<Error, DeleteUserRequest>
function getUser(userId: number): Promise<Either<Error, User>>
function deleteUserDb(user: User): Promise<Id<User>>
const deleteUser = (req): EitherAsync<Error, Id<User>> =>
EitherAsync(async ({ liftEither, fromPromise, throwE }) => {
// when you have Either<L, R> and you want to get R out
const request = await liftEither(validateRequest(req))
try {
// when you have Promise<Either<L, R>> and you want to get R out
const user = await fromPromise(getUser(request.userId))
} catch {
throwE(Error.UserDoesNotExist)
}
return deleteUserDb(user)
})
const promise: Promise<Either<Error, Id<User>>> =
deleteUser(req).run()
const deleteUser = (req): EitherAsync<Error, Id<User>> =>
EitherAsync.liftEither(validateRequest(req))
// when you have
// Promise<Either<L, R>> or EitherAsync<L, R> (both work)
// and you want to chain it
.chain(request => getUser(request.userId))
.mapLeft(_ => Error.UserDoesNotExist)
// when you have Promise<T> and you want to chain it
.chain(user => EitherAsync(() => deleteUserDb(user)))
const promise: Promise<Either<Error, Id<User>>> =
deleteUser(req).run()
EitherAsync<Error, number>(({ liftEither, fromPromise }) => Promise.resolve(5))
➔
EitherAsync<Error, number>
EitherAsync.fromPromise(() => Promise.resolve(Right(5)))
➔
EitherAsync<never, number>
EitherAsync.liftEither(Right(5))
➔
EitherAsync<never, number>
EitherAsync.lefts([
EitherAsync.liftEither(Left('Server error')),
EitherAsync.liftEither(Left('Wrong password')),
EitherAsync(async () => 'foo@bar.com')
])
➔
Promise {<resolved>: ['Server error', 'Wrong password']}
EitherAsync.rights([
EitherAsync(async () => 10),
EitherAsync.liftEither(Left('Invalid input')),
EitherAsync(async () => 5)
])
➔
Promise {<resolved>: [10, 5]}
EitherAsync.sequence([EitherAsync(async () => 1), EitherAsync(async () => 2)).run()
EitherAsync.sequence([EitherAsync(async () => 1), EitherAsync(() => { throw 'Error' })])).run()
➔
➔
Promise {<resolved>: Right([1, 2])}
Promise {<resolved>: Left('Error')}
EitherAsync<string, never>(({ liftEither }) => liftEither(Left('Error'))).run()
EitherAsync<string, never>(() => Promise.reject('Something happened')).run()
EitherAsync<Error, never>(() => { throw Error('Something happened') }).run()
EitherAsync<string, number>(() => Promise.resolve(5)).run()
➔
➔
➔
➔
Promise {<resolved>: Left('Error')}
Promise {<resolved>: Left('Something happened')}
Promise {<resolved>: Left(Error('Something happened'))}
Promise {<resolved>: Right(5)}
EitherAsync(() => Promise.resolve(5)).bimap(identity, x => x + 1).run()
EitherAsync(() => Promise.reject(5)).bimap(x => x + 1, identity).run()
➔
➔
Promise {<resolved>: Right(6)}
Promise {<resolved>: Left(6)}
EitherAsync(() => Promise.resolve(5)).map(x => x + 1).run()
➔
Promise {<resolved>: Right(6)}
EitherAsync(() => throw new Error()).mapLeft(_ => ({ status: 500 })).run()
EitherAsync(() => Promise.resolve(5)).mapLeft(x => x + 1).run()
➔
➔
Promise {<resolved>: Left({ status: 500 })}
Promise {<resolved>: Right(5)}
EitherAsync(async () => 5).chain(x => EitherAsync(async () => x + 1)).run()
EitherAsync(async () => 5).chain(async (x) => Right(x + 1)).run()
➔
➔
Promise {<resolved>: Right(6)}
Promise {<resolved>: Right(6)}
EitherAsync(({ throwE }) => throwE(500))
.chainLeft(x => EitherAsync(() => Promise.resolve(6)))
.run()
➔
Promise {<resolved>: Right(6)}
EitherAsync<string, number>(() => Promise.resolve(5)).swap().run()
EitherAsync(() => Promise.reject('Something happened')).swap().run()
➔
➔
Promise {<resolved>: Left(5)}
Promise {<resolved>: Right('Something happened')}
EitherAsync.liftEither(Left('Error')).ifLeft((err) => console.log(err))
EitherAsync.liftEither(Right(5)).ifLeft(() => console.log('Unexpected error'))
➔
➔
// Error
EitherAsync.liftEither(Left('Error')).ifRight((result) => console.log(result))
EitherAsync.liftEither(Right(5)).ifRight((result) => console.log(result))
➔
➔
// 5
EitherAsync.liftEither(Left('Error')).finally(() => console.log('It runs!))
EitherAsync.liftEither(Right(5)).finally(() => console.log('It runs!))
➔
➔
// It runs!
// It runs!
EitherAsync(async ({ liftEither }) => {
const value: number = await liftEither(Right(5))
}).run()
➔
Promise {<resolved>: Right(5)}
EitherAsync(async ({ fromPromise }) => {
const value: number = await fromPromise(Promise.resolve(Right(5)))
}).run()
➔
Promise {<resolved>: Right(5)}
EitherAsync<string, number>(async ({ liftEither, throwE })
const value: number = await liftEither(Right(5))
throwE('Test')
return value
}).run()
➔
Promise {<resolved>: Left('Test')}