UNPKG

@hypernetlabs/utils

Version:
165 lines 6.44 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ResultUtils = void 0; const delay_1 = __importDefault(require("delay")); const neverthrow_1 = require("neverthrow"); class ResultUtils { static combine(asyncResultList) { return neverthrow_1.ResultAsync.fromPromise(Promise.all(asyncResultList), (e) => { return e; }).andThen(ResultUtils.combineResultList); } static combineResultList(resultList) { return resultList.reduce((acc, result) => { return acc.isOk() ? result.isErr() ? (0, neverthrow_1.err)(result.error) : acc.map((values) => { values.push(result.value); return values; }) : acc; }, (0, neverthrow_1.ok)([])); } static race(asyncResultList) { return neverthrow_1.ResultAsync.fromPromise(Promise.race(asyncResultList), (e) => { return e; }).andThen(ResultUtils.resultRace); } static resultRace(result) { return result.isErr() ? (0, neverthrow_1.err)(result.error) : (0, neverthrow_1.ok)(result.value); } static fromThrowableResult(throwableCallback) { const throwable = neverthrow_1.Result.fromThrowable(throwableCallback, (err) => { return err; }); return throwable(); } static executeSerially(funcList) { // const results = new Array<T>(); // // for (const func of funcList) { // // func().map((val) => {}) // // } // try { // funcList.reduce( // (p: ResultAsync<void, E>, x) => // p.andThen(_ => { // return x() // .map((result) => { // results.push(result); // }) // .mapErr((e) => { // throw e; // }); // }), // okAsync<void, E>(undefined) // ); // } // catch (e) { // return errAsync(e); // } const func = async () => { const results = new Array(); for (const func of funcList) { const result = await func(); if (result.isErr()) { throw result.error; } else { results.push(result.value); } } return results; }; return neverthrow_1.ResultAsync.fromPromise(func(), (e) => { return e; }); } static backoffAndRetry(func, acceptableErrors, maxAttempts, baseSeconds = 5) { if (maxAttempts != null && maxAttempts < 1) { throw new Error("maxAttempts must be 1 or more!"); } if (baseSeconds < 1) { throw new Error("baseSeconds must be 1 or more!"); } const runAndCheck = (currentAttempt, nextAttemptSecs, lastError) => { if (maxAttempts != null && currentAttempt > maxAttempts) { if (lastError == null) { throw new Error("Error before first function run; logical error! maxAttempts must be 1 or more!"); } return (0, neverthrow_1.errAsync)(lastError); } // Check the result. If it's not an error, we're done! // If it's an error, check the error type against acceptableErrors. If it's in the list, // wait some amount of time and try again. // If it is not in the list, return the error and stop. return func().orElse((e) => { let retry = false; for (const acceptableError of acceptableErrors) { if (e instanceof acceptableError) { retry = true; break; } } if (retry) { return neverthrow_1.ResultAsync.fromSafePromise((0, delay_1.default)(nextAttemptSecs)).andThen(() => { return runAndCheck(++currentAttempt, nextAttemptSecs * 2, e); }); } return (0, neverthrow_1.errAsync)(e); }); }; return runAndCheck(1, baseSeconds, null); } /** * filter() is a normal filter method that works with async callbacks. * This works like a nomral array filter() call, except the callback returns * a ResultAsync<boolean> instead of just boolean. * @param arr the source array * @param callback a function that returns a ResultAsync<boolean>; if it returns true then the source value is included in the result. * @returns a ResultAsync containing an array of source values where the callback returns true. */ static filter(arr, callback) { const filterVals = new Array(); return ResultUtils.combine(arr.map((val) => { return callback(val).map((result) => { if (result) { filterVals.push(val); } }); })).map(() => { return filterVals; }); } /** * map() is a way to combine multiple async callbacks. * This works like a normal array map() call, except the callbacks return ResultAsync. * It will combine all the results and return a single ResultAsync with an array of the mapped * values. * @param arr The source array of objects * @param callback A function that returns a ResultAsync and a value * @returns A ResultAsync containing an array of the mapped values or the first error. */ static map(arr, callback) { const mapVals = new Array(); return ResultUtils.combine(arr.map((val) => { return callback(val).map((result) => { mapVals.push(result); }); })).map(() => { return mapVals; }); } static delay(ms) { return neverthrow_1.ResultAsync.fromSafePromise(new Promise((resolve) => { setTimeout(() => { resolve(); }, ms); })); } } exports.ResultUtils = ResultUtils; //# sourceMappingURL=ResultUtils.js.map