import { IS_PROMISE, IS_SYMBOL } from "./consts";
import {
Curry1,
Curry2CallbackType, Curry2,
Curry3CallbackType, Curry3,
Curry4CallbackType, Curry4, Func, NoPromise, Curry1CallbackType
} from "./types";
import { isFunction, ObjectInterface } from "@daybrush/utils";
import { reduceAsyncArrayF } from "./array/asyncArray";
import { CallbackType } from "./event/event";
/**
* @namespace utils
*/
/**
* @memberof utils
*/
export function isPromise<T = any>(value: any): value is Promise<any> {
return IS_PROMISE && (value instanceof Promise);
}
/**
* @memberof utils
*/
export function isIterable<T = any>(iter: any): iter is Iterable<T> | AsyncIterable<T> {
return IS_SYMBOL && !!(iter && (iter[Symbol.iterator] || iter[Symbol.asyncIterator]));
}
/**
* @memberof utils
*/
export function isIterator<T = any>(iter: any): iter is Iterator<T> {
return iter && isFunction(iter.next);
}
export function exec<T, U = T>(f: (pv: T) => U, v: Promise<T>): Promise<U>;
export function exec<T, U = T>(f: (pv: T) => U, v: NoPromise<T>): U;
export function exec<T, U = T>(f: (pv: T) => U, v: Promise<T> | T): Promise<U> | U;
/**
* @memberof utils
*/
export function exec<T, U = T>(f: (pv: T) => U, v: T | Promise<T>) {
return isPromise(v) ? v.then(pv => f(pv)) : f(v);
}
export function curry<A>(f: () => A): () => A;
export function curry<A, B>(f: Curry1CallbackType<A, B>): Curry1<A, B>;
export function curry<A, B, C>(f: Curry2CallbackType<A, B, C>): Curry2<A, B, C>;
export function curry<A, B, C, D>(f: Curry3CallbackType<A, B, C, D>): Curry3<A, B, C, D>;
export function curry<A, B, C, D, E>(f: Curry4CallbackType<A, B, C, D, E>): Curry4<A, B, C, D, E>;
/**
* @memberof utils
*/
export function curry(f: CallbackType): any {
const length = f.length;
if (length === 0) {
return f;
}
function nest(i: number, args: any[]) {
return (...args2: any[]) => {
const length2 = i - args2.length;
return length2 <= 0 ? f(...args, ...args2) : nest(length2, args.concat(args2));
};
}
return nest(length, []);
}
export function _pipe(args: Func[]): Func {
return (a: any) => {
return reduceAsyncArrayF((prev, cur) => cur(prev), a, args);
};
}
export function pipe<A, B, C, D, E>(a: Func<A, B>, b: Func<B, C>, c: Func<C, D>, d: Func<D, E>): Func<A, E>;
export function pipe<A, B, C, D>(a: Func<A, B>, b: Func<B, C>, c: Func<C, D>): Func<A, D>;
export function pipe<A, B, C>(a: Func<A, B>, b: Func<B, C>): Func<A, C>;
/**
* @memberof utils
*/
export function pipe(...args: Func[]): Func {
return _pipe(args);
}
export function compose<A, B, C, D, E>(a: Func<D, E>, b: Func<C, D>, c: Func<B, C>, d: Func<A, B>): Func<A, E>;
export function compose<A, B, C, D>(a: Func<C, D>, b: Func<B, C>, c: Func<A, B>): Func<A, D>;
export function compose<A, B, C>(a: Func<B, C>, b: Func<A, B>): Func<A, C>;
/**
* @memberof utils
*/
export function compose(...args: Func[]): Func {
return _pipe(args.reverse());
}
export function* values<T>(obj: ObjectInterface<T>) {
for (const key in obj) {
yield obj[key as keyof ObjectInterface<T>];
}
}