ts-async-results
v0.7.10
Published
An Async implementation of the awesome github.com/vultix/ts-results.
Downloads
328
Maintainers
Readme
ts-async-results
An Async implementation of the awesome ts-results.
For an intro into the Result's API check out the above link or Rust's own Result API.
This library only addresses the Async component of the Result.
LOOKING FOR CONTRIBUTORS
Contents
Installation
$ npm install ts-async-results
or
$ yarn add ts-async-results
Usage
import { AsyncResultWrapper, AsyncErr, AsyncOk } from 'ts-async-results';
Creation
let okAsyncResult: AsyncResult<number, Error> = new AsyncOk(10);
let okResult2 = AsyncOk<number, Error>(10); // Exact same as above
let errorResult: AsyncResult<number, Error> = new AsyncOk(new Error('bad number!'));
let errorResult2 = new AsyncOk<number, Error>(new Error('bad number!')); // Exact same as above
Wrap other Result or Async Result
// From Result
new AsyncResultWrapper(new Ok(10));
// From Result Function
new AsyncResultWrapper(() => new Ok(10));
// From Result Async Function
let okFromResultAsyncFn = new AsyncResultWrapper(async () => {
await delay(1);
return new Ok(10)
});
// From Async
new AsyncResultWrapper(new AsyncOk(10));
// From Async Result Function
new AsyncResultWrapper(() => new AsyncOk(10));
// From Async Result Async Function :)
new AsyncResultWrapper(async () => {
await delay(1);
return new AsyncOk(10)
});
// Works in the same way with AsyncErr or the alias AsyncReult.toAsyncResult()
Map and MapErr
const httpAsyncResult = new AsyncResultWrapper(async () => {
try {
const { data } = await http.get('/api');
return new Ok(data)
} catch (e) {
return new Err('BadRequest');
}
});
httpAsyncResult
.map((myData) => {
// do stuff with the data
})
.mapErr((err) => {
console.error(err);
});
Flatmap
const getResourceAsyncResult = () => new AsyncResultWrapper(async () => {
try {
const { data } = await http.get('/api');
return new Ok(data)
} catch (e) {
return new Err('BadRequest');
}
});
const postResourceAndAnotherAsyncResult = (id: string) => new AsyncResultWrapper(async () => {
try {
const { data } = await http.post('/api', { id });
return new Ok(data)
} catch (e) {
return new Err('BadRequest');
}
});
getResourceAsyncResult()
.flatMap((myData) => {
// do some more async stuff with the data and return another AsyncResult
return postResourceAndAnotherAsyncResult(myData.id);
})
.map((myData) => {
// do stuff with the data
})
.mapErr((err) => {
console.error(err);
});
FlatMapErr
const getResourceAsyncResultWithRetry = () => new AsyncResultWrapper(async () => {
try {
const { data } = await http.get('/api');
return new Ok(data)
} catch (e) {
return new Err('BadRequest');
}
})
.flatMapErr((err) => {
// you can intercept an Err path and transform it into a (potential) Ok path
if (err === 'CONNECTION_FAILED') {
const retryAttemptAsyncResult = getResourceAsyncResult();
// If the attempt failed due to a network error automatically retry
// NOTE: Don't use this code in production as it's veeeery inefficient!
// It's only meant for demonstration purposes.
return retryAttemptAsyncResult;
}
else {
// We always return back an AsyncResult
return new AsyncErr(err);
}
});
getResourceAsyncResultWithRetry()
.map((myData) => {
// do stuff with the data
})
.mapErr((err) => {
console.error(err);
});
Expect
To use Expect
we make use of the fact that an AsyncResult resolves to a simple Result.
let goodAsyncResult = new AsyncOk(1);
let badAsyncResult = new AsyncErr("something went wrong");
let goodResult = (await goodAsyncResult.resolve());
let badResult = (await goodAsyncResult.resolve());
goodResult.expect('goodResult should be a number'); // 1
badResult.expect('badResult should be a number'); // throws Error("badResult should be a number - Error: something went wrong")
Empty
function checkIsValid(isValid: boolean): AsyncResult<void, Error> {
if (isValid) {
return AsyncOk.EMPTY;
} else {
return new AsyncErr("Not valid");
}
}
Resolve
Calling myAsyncResult.resolve()
transforms it into a Promise<Result<T, E>>
Ok Path
let asyncResult = new AsyncOk(1);
let result = (await goodAsyncResult.resolve());
console.log(result.val); // 1
Error Path
Note: Calling resolve()
does NOT throw when the value is an Error. See ResolveUnwrap if you need that behavior
let asyncResult = new AsyncErr('SimpleErr');
let result = (await goodAsyncResult.resolve());
console.log(result.val); // SimpleErr
Unwrap
To use Unwrap
we make use of the fact that an AsyncResult resolves to a simple Result.
let goodAsyncResult = new AsyncOk(1);
let badAsyncResult = new AsyncErr("something went wrong");
let goodResult = (await goodAsyncResult.resolve());
let badResult = (await goodAsyncResult.resolve());
goodResult.unwrap(); // 1
badResult.unwrap(); // throws Error("something went wrong")
UnwrapOr
To use UnwrapOr
we make use of the fact that an AsyncResult resolves to a simple Result.
let goodAsyncResult = new AsyncOk(1);
let badAsyncResult = new AsyncErr("something went wrong");
let goodResult = (await goodAsyncResult.resolve());
let badResult = (await goodAsyncResult.resolve());
let goodResult = Ok(1);
let badResult = Err(new Error("something went wrong"));
goodResult.unwrapOr(5); // 1
badResult.unwrapOr(5); // 5
ResolveUnwrap
Combines Resolve and Unwrap functionalities.
let goodAsyncResult = new AsyncOk(1);
console.log(await goodAsyncResult.resolveUnwrap()); // 1
let badAsyncResult = new AsyncErr("something went wrong");
console.log(await badAsyncResult.resolveUnwrap()); // throws Error("something went wrong")
ResolveUnwrapOr
Similar to "ResolveUnwrap" but provides a fallback for the Error path. The Ok path remains unaffected!
let goodAsyncResult = new AsyncOk(1);
console.log(await goodAsyncResult.resolveUnwrapor(5)); // 1
let badAsyncResult = new AsyncErr("something went wrong");
console.log(await badAsyncResult.resolveUnwrapOr(5)); // 5
Combining Results
ts-async-results
has one helper function for operating over n Result
objects.
AsyncResult.all
Either returns all of the Ok
values, or the first Err
value
Ok Path
const allResult = AsyncResult.all(
new AsyncOk(2),
new AsyncOk('a string'),
);
(await allResult.resolve()).unwrap()) // [2, 'a string'];
Err Path
const allResult = AsyncResult.all(
new AsyncOk(2),
new AsyncErr('AnError'),
);
(await allResult.resolve()).unwrap()) // AnError
AsyncResult.any
TBD