safe-result
Version:
Create safe results that are either successes or failures
131 lines • 4.08 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.all = exports.allSettled = void 0;
const result_1 = require("./result");
const internal_1 = require("./internal");
const typeguards_1 = require("./typeguards");
/**
* @internal
*/
async function guard(res, noThrow) {
try {
const x = res.map((r) => {
if ((0, internal_1.isPromise)(r)) {
return new Promise((resolve, reject) => {
r.then((rres) => resolve((0, internal_1.toSuccess)(rres))).catch((e) => noThrow ? resolve((0, internal_1.toFailure)(e)) : reject((0, internal_1.toFailure)(e)));
});
}
else {
if ((0, typeguards_1.isResult)(r)) {
return r.success
? Promise.resolve(r)
: noThrow
? Promise.resolve(r)
: Promise.reject(r);
}
else {
return (0, internal_1.isError)(r)
? noThrow
? Promise.resolve((0, result_1.failure)(r))
: Promise.reject((0, result_1.failure)(r))
: Promise.resolve((0, result_1.success)(r));
}
}
});
const resolved = (await Promise.all(x));
if (noThrow) {
return new result_1.SuccessAndFailureResult(resolved.filter(typeguards_1.isSuccess).map((s) => s.result), resolved.filter(typeguards_1.isFailure).map((e) => e.error));
}
else {
return new result_1.SuccessResult(resolved.map((s) => s.result));
}
}
catch (e) {
const fr = (0, typeguards_1.isFailure)(e) ? e : (0, result_1.failure)(e);
return new result_1.FailureResult(fr.error);
}
}
/**
* Creates a `Promise` that resovles after all values have either resolved or
* rejected.
*
* @note The returned [[SuccessAndFailureResult]] object can indicate being
* both a `success` and `failure`.
*
* If `SuccessAndFailureResult.success` is `true` there are one or more resovled
* promises.
*
* Likewise, if `SuccessAndFailureResult.failure` is `true` there are one or
* more rejected promises.
*
* @example
*
* ```ts
* const args = [
* Promise.resolve(success(1)),
* Promise.resolve(success(2)),
* Promise.reject(failure(new Error('First failure'))),
* ]
*
* const res = await Result.allSettled(args)
*
* if (res.success) { // Will be `true` in this case
* console.log('Values:', res.result.join(', '))
* // Values: 1, 2
* }
*
* if (res.failure) { // Will also be true in this case
* console.error('Errors:', res.error.map((e) => e.message).join(', '))
* // Errors: First failure
* }
* ```
*
* @param values
*/
async function allSettled(values) {
return guard(values, true);
}
exports.allSettled = allSettled;
/**
* Creates a `Promise` that resolves to either a [[SuccessResult]] or a
* [[FailureResult]].
*
* This behaves pretty much the same as `Promise.all()`, so it will abort and
* return a [[FailureResult]] as soon as a value is a rejected value.
*
* @example _Example with all resolved promises_
*
* ```ts
* const values = [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)]
* const [res, err] = (await Result.all(values)).unwrap()
*
* if (err) { // This will never be `true` in this case
* return
* }
*
* console.log(
* res.map((num) => `Result ${num}`).join(', ')
* )
*
* // Result 1, Result 2, Result 3
* ```
*
* @example _Example where one or more promises are rejected_
*
* ```ts
* const values = [Promise.resolve(1), Promise.reject(2), Promise.resolve(3)]
* const [res, err] = (await Result.all(values)).unwrap()
*
* if (err) { // This will always be `true` in this case
* console.error('An error occured:', err.message)
* return
* }
* ```
*
* @param values
*/
async function all(values) {
return guard(values, false);
}
exports.all = all;
//# sourceMappingURL=collection.js.map