mauss
Version:
lightweight, modular, type-safe utilities
90 lines (89 loc) • 2.74 kB
JavaScript
/**
* A function that will execute a `work` asynchronously and will not throw an error.
*
* @param work a function with an asynchronous operation
* @template T the type of the data returned by the promise
* @returns an object with either `data` or `error` property
* @example
* ```typescript
* const { data, error } = await attempt(async () => {
* // some async operation
* return 'result';
* });
* if (error) { // could also be `data`
* // log error or do other things
* }
* ```
*/
export async function attempt(work) {
try {
return { data: await work() };
}
catch (error) {
return { error };
}
}
/**
* A function that will execute a `work` synchronously and will not throw an error.
*
* @param work a function with a synchronous operation
* @template T the type of the data returned by the function
* @returns an object with either `data` or `error` property
* @example
* ```typescript
* const { data, error } = attempt(() => {
* // some sync operation
* return 'result';
* });
* if (error) { // could also be `data`
* // log error or do other things
* }
* ```
*/
attempt.sync = function (work) {
try {
return { data: work() };
}
catch (error) {
return { error };
}
};
attempt.wrap = function (fn) {
return (...args) => {
try {
return { data: fn(...args) };
}
catch (error) {
return { error };
}
};
};
/**
* A type-safe higher-order function that accepts a function with one or more parameters and returns a function that can take in one or more arguments with a max of the parameters length.
* If the total arguments provided has not yet reached the initial function parameters length, it will return a function until all the required parameters are fulfilled.
*
* @returns a curried function to take in the arguments
*/
export function curry(fn, expected = fn.length) {
return (...args) => {
if (args.length === expected)
return fn(...args);
if (args.length > expected)
return fn(...args.slice(0, expected));
return curry((...next) => fn(...[...args, ...next]), expected - args.length);
};
}
/**
* A type-safe higher-order function that accepts any number of arguments, it returns a function with the parameters of the first function passed and a return type/value of the last function.
*
* @returns a function that takes in the initial type and returns the final type
*/
export function pipe(...functions) {
return (arg) => {
let pipeline = arg;
for (let i = 0; i < functions.length; i++) {
pipeline = functions[i](pipeline);
}
return pipeline;
};
}