///
export function functionalUpdate(updater, input) {
    return typeof updater === 'function' ? updater(input) : updater;
}
export function noop() {
    //
}
export function makeStateUpdater(key, instance) {
    return (updater) => {
        instance.setState((old) => {
            return {
                ...old,
                [key]: functionalUpdate(updater, old[key]),
            };
        });
    };
}
export function isFunction(d) {
    return d instanceof Function;
}
export function isNumberArray(d) {
    return Array.isArray(d) && d.every((val) => typeof val === 'number');
}
export function flattenBy(arr, getChildren) {
    const flat = [];
    const recurse = (subArr) => {
        subArr.forEach((item) => {
            flat.push(item);
            const children = getChildren(item);
            if (children === null || children === void 0 ? void 0 : children.length) {
                recurse(children);
            }
        });
    };
    recurse(arr);
    return flat;
}
export function memo(getDeps, fn, opts) {
    let deps = [];
    let result;
    return (depArgs) => {
        var _a;
        let depTime;
        if (opts.key && opts.debug)
            depTime = Date.now();
        const newDeps = getDeps(depArgs);
        const depsChanged = newDeps.length !== deps.length ||
            newDeps.some((dep, index) => deps[index] !== dep);
        if (!depsChanged) {
            return result;
        }
        deps = newDeps;
        let resultTime;
        if (opts.key && opts.debug)
            resultTime = Date.now();
        result = fn(...newDeps);
        (_a = opts === null || opts === void 0 ? void 0 : opts.onChange) === null || _a === void 0 ? void 0 : _a.call(opts, result);
        if (opts.key && opts.debug) {
            if (opts === null || opts === void 0 ? void 0 : opts.debug()) {
                const depEndTime = Math.round((Date.now() - depTime) * 100) / 100;
                const resultEndTime = Math.round((Date.now() - resultTime) * 100) / 100;
                const resultFpsPercentage = resultEndTime / 16;
                const pad = (str, num) => {
                    str = String(str);
                    while (str.length < num) {
                        str = ` ${str}`;
                    }
                    return str;
                };
                console.info(`%c⏱ ${pad(resultEndTime, 5)} /${pad(depEndTime, 5)} ms`, `
            font-size: .6rem;
            font-weight: bold;
            color: hsl(${Math.max(0, Math.min(120 - 120 * resultFpsPercentage, 120))}deg 100% 31%);`, opts === null || opts === void 0 ? void 0 : opts.key);
            }
        }
        return result;
    };
}
export function getMemoOptions(tableOptions, debugLevel, key, onChange) {
    return {
        debug: () => { var _a; return (_a = tableOptions === null || tableOptions === void 0 ? void 0 : tableOptions.debugAll) !== null && _a !== void 0 ? _a : tableOptions[debugLevel]; },
        key: process.env.NODE_ENV === 'development' && key,
        onChange,
    };
}
