UNPKG

@softwareventures/maintain-project

Version:

Automatically create and maintain TypeScript projects with standard settings for Software Ventures Limited

135 lines 4.64 kB
import { map } from "@softwareventures/array"; import { concatMap, filter, fold, toArray } from "@softwareventures/iterable"; import { asyncFilter, asyncFold, combineAsync } from "../collections/async-iterable.js"; export function success(value) { return { type: "success", value }; } export function failure(reasons = []) { return { type: "failure", reasons }; } export function isSuccess(result) { return result.type === "success"; } export function isFailure(result) { return result.type === "failure"; } export function mapResult(result, f) { if (result.type === "success") { return { type: "success", value: f(result.value) }; } else { return result; } } export function mapResultFn(f) { return result => mapResult(result, f); } export async function mapAsyncResult(result, f) { if (result.type === "success") { return Promise.resolve(f(result.value)).then(value => ({ type: "success", value })); } else { return result; } } export function mapAsyncResultFn(f) { return async (result) => mapAsyncResult(result, f); } export function bindResult(result, f) { if (result.type === "success") { return f(result.value); } else { return result; } } export function bindResultFn(f) { return result => bindResult(result, f); } export async function bindAsyncResult(result, f) { if (result.type === "success") { return Promise.resolve(f(result.value)); } else { return result; } } export function bindAsyncResultFn(f) { return async (result) => bindAsyncResult(result, f); } export function mapFailure(result, f) { if (result.type === "success") { return result; } else { return { type: "failure", reasons: map(result.reasons, f) }; } } export function mapFailureFn(f) { return reason => mapFailure(reason, f); } export function bindFailure(result, f) { if (result.type === "success") { return result; } else { return f(result.reasons); } } export function bindFailureFn(f) { return result => bindFailure(result, f); } export function combineResults(results) { return failure(toArray(concatMap(filter(results, isFailure), ({ reasons }) => reasons))); } export async function combineAsyncResults(results) { return combineAsync(asyncFilter(results, isFailure)).then(failures => failures.length === 0 ? success() : failure(toArray(concatMap(failures, failure => failure.reasons)))); } export function chainResults(initial, actions) { return fold(actions, bindResult, success(initial)); } export function chainResultsFn(actions) { return initial => chainResults(initial, actions); } export async function chainAsyncResults(initial, actions) { return fold(actions, async (accumulator, action) => accumulator.then(bindAsyncResultFn(action)), Promise.resolve({ type: "success", value: initial })); } export function chainAsyncResultsFn(actions) { return async (initial) => chainAsyncResults(initial, actions); } export async function tolerantFoldAsyncResults(iterable, f, initial) { return asyncFold(iterable, async ({ accumulator, reasons }, element) => Promise.resolve(f(accumulator, element)) .then(mapResultFn(accumulator => ({ accumulator, reasons }))) .then(bindFailureFn(reasons2 => success({ accumulator, reasons: [...reasons, ...reasons2] }))) .then(throwFailure), { accumulator: initial, reasons: [] }).then(({ accumulator, reasons }) => reasons.length === 0 ? success(accumulator) : failure(reasons)); } export function tolerantFoldAsyncResultsFn(f, initial) { return async (iterable) => tolerantFoldAsyncResults(iterable, f, initial); } export function allResults(results) { return fold(results, (acc, result) => bindResult(acc, accValues => mapResult(result, value => [...accValues, value])), success([])); } export async function allAsyncResults(results) { return Promise.all(results).then(results => allResults(results)); } export function toNullable(result) { return result.type === "success" ? result.value : null; } export async function toAsyncNullable(result) { return result.then(toNullable); } export function throwFailure(result, message) { if (result.type === "success") { return result.value; } else { throw new Error((message == null ? "" : `${message}:\n`) + map(result.reasons, reason => JSON.stringify(reason)).join("\n")); } } export function throwFailureFn(message) { return result => throwFailure(result, message); } //# sourceMappingURL=result.js.map