export function diff(oldList, newList, key) {
    if (Array.isArray(oldList)) {
        return calculateListDiff(oldList, newList, key);
    }
    if (typeof oldList === "object") {
        return calculateObjectDiff(oldList, newList);
    }
    return {
        added: [],
        removed: [],
        modified: [],
    };
}
export function calculateObjectDiff(oldObject, newObject) {
    var tOldKeys = Object.getOwnPropertyNames(oldObject);
    var tNewKeys = Object.getOwnPropertyNames(newObject);
    return tNewKeys.reduce(function (result, key) {
        var tOldValue = oldObject[key];
        if (tOldValue === undefined) {
            result.added.push(key);
        }
        else {
            var tNewValue = newObject[key];
            if (tNewValue !== tOldValue) {
                result.modified.push(key);
            }
        }
        return result;
    }, {
        modified: [],
        added: [],
        removed: tOldKeys.filter(function (key) { return !newObject[key]; }),
    });
}
export function calculateListDiff(oldList, newList, key) {
    var tPrevElements = oldList.reduce(function (prevElements, element) {
        prevElements[getKey(element, key)] = element;
        return prevElements;
    }, {});
    var tNewElements = newList.reduce(function (newElements, element) {
        newElements[getKey(element, key)] = element;
        return newElements;
    }, {});
    return {
        added: Object.getOwnPropertyNames(tNewElements).filter(function (element) { return !tPrevElements[element]; }),
        removed: Object.getOwnPropertyNames(tPrevElements).filter(function (element) { return !tNewElements[element]; }),
        modified: [],
    };
}
function getKey(element, key) {
    return typeof element === "object" ? element[key] : element;
}
