/**
 * Javascript utility functions
 *
 * @since 3.0.0
 *
 */

export function delayExecution(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms));
}
export function debounce(callback) {
    let timeout;
    return (argument) => {
        clearTimeout(timeout);
        timeout = setTimeout(() => callback(argument), 500);
    };
}
export function cloneDeep(entity) {
    const referenceTypes = ["Array", "Object"];
    const entityType = Object.prototype.toString.call(entity);
    if (
        !new RegExp(referenceTypes.join("|")).test(entityType) ||
        entity instanceof WeakMap ||
        entity instanceof WeakSet
    )
        return entity;

    const c = new entity.constructor();
    return Object.assign(
        c,
        ...Object.keys(entity).map((prop) => ({
            [prop]: cloneDeep(entity[prop]),
        }))
    );
}
export function debouncePromise(fn, ms = 0) {
    let timeoutId;
    const pending = [];
    return (...args) =>
        new Promise((res, rej) => {
            clearTimeout(timeoutId);
            timeoutId = setTimeout(() => {
                const currentPending = [...pending];
                pending.length = 0;
                Promise.resolve(fn.apply(this, args)).then(
                    data => {
                        currentPending.forEach(({ resolve }) => resolve(data));
                    },
                    error => {
                        currentPending.forEach(({ reject }) => reject(error));
                    }
                );
            }, ms);
            pending.push({ resolve: res, reject: rej });
        });
}
