"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ArrayMap = exports.combineErrorStacks = exports.stripStack = exports.getErrorStack = exports.assertNever = exports.getWorkerThreads = exports.nodeSupportsWorkerThreads = exports.browserSupportsWebWorkers = exports.isBrowser = void 0;
/**
 * Returns true if running in th browser (if not, then we're in NodeJS)
 */
function isBrowser() {
    return !(process && process.hasOwnProperty('stdin'));
}
exports.isBrowser = isBrowser;
function browserSupportsWebWorkers() {
    // @ts-ignore
    return !!(isBrowser() && window.Worker);
}
exports.browserSupportsWebWorkers = browserSupportsWebWorkers;
function nodeSupportsWorkerThreads() {
    const workerThreads = getWorkerThreads();
    return !!workerThreads;
}
exports.nodeSupportsWorkerThreads = nodeSupportsWorkerThreads;
function getWorkerThreads() {
    try {
        const workerThreads = require('worker_threads');
        return workerThreads;
    }
    catch (e) {
        return null;
    }
}
exports.getWorkerThreads = getWorkerThreads;
/**
 * Helper function to simply assert that the value is of the type never.
 * Usage: at the end of if/else or switch, to ensure that there is no fallthrough.
 */
function assertNever(_value) {
    // does nothing
}
exports.assertNever = assertNever;
function getErrorStack(err) {
    if (typeof err === 'object') {
        const stack = err.stack;
        if (stack)
            return stack;
        return `${err}`;
    }
    else {
        return `${err}`;
    }
}
exports.getErrorStack = getErrorStack;
function stripStack(stack, matchLines) {
    if (!stack)
        return stack;
    const stackLines = stack.split('\n');
    let matchIndex = -1;
    for (let i = 0; i < stackLines.length; i++) {
        let matching = false;
        for (const line of matchLines) {
            if (stackLines[i] && stackLines[i].match(line)) {
                if (matchIndex === -1)
                    matchIndex = i;
                matching = true;
                i += 1;
            }
            else {
                matching = false;
                break;
            }
        }
        if (matching) {
            return stackLines.slice(0, matchIndex).join('\n');
        }
    }
    // else, return the original:
    return stack;
}
exports.stripStack = stripStack;
function combineErrorStacks(orgError, ...stacks) {
    if (typeof orgError === 'object') {
        const err = new Error(orgError.message);
        err.stack = combineErrorStacks(`${orgError.stack}`, ...stacks);
        return err;
    }
    else {
        return orgError + '\n' + stacks.join('\n');
    }
}
exports.combineErrorStacks = combineErrorStacks;
/** A specific type of Map which contains an array of values */
class ArrayMap extends Map {
    constructor() {
        super();
    }
    /** Appends new elements to the end of an array, and returns the new length of the array.  */
    push(key, value) {
        const arr = this.get(key);
        if (!arr) {
            this.set(key, [value]);
            return 1;
        }
        else {
            arr.push(value);
            return arr.length;
        }
    }
    /** Removes an element from the array, returns true if the element was found and removed */
    remove(key, value) {
        let removedSomething = false;
        const arr = this.get(key);
        if (arr) {
            const index = arr.indexOf(value);
            if (index !== -1) {
                arr.splice(index, 1);
                removedSomething = true;
            }
            if (arr.length === 0) {
                this.delete(key);
            }
        }
        return removedSomething;
    }
    arraySize(key) {
        var _a, _b;
        return (_b = (_a = this.get(key)) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
    }
    /** The total number of elements in all of the arrays  */
    get totalSize() {
        let total = 0;
        for (const arr of this.values()) {
            total += arr.length;
        }
        return total;
    }
}
exports.ArrayMap = ArrayMap;
//# sourceMappingURL=lib.js.map