var FetchCache = /** @class */ (function () {
    function FetchCache(params) {
        this.dataHolder = new Map();
        this.fetchPromises = new Map();
        this.createIdentifier = FetchCache.makeIdentifier;
        this.isCacheValid = function () { return true; };
        this.fetch = params.fetch;
        if (params.createIdentifier !== undefined) {
            this.createIdentifier = params.createIdentifier;
        }
        if (params.isCachedValid) {
            this.isCacheValid = params.isCachedValid;
        }
    }
    /**
     * Adds a resource to the cache
     *
     * @param {IdentificationData} identification
     * @param {Data} data
     */
    FetchCache.prototype.add = function (identification, data) {
        var identifer = this.createIdentifier(identification);
        this.dataHolder.set(identifer, data);
    };
    /**
     * Synchronously gets a resource from the cache. returns undefined for not existing resources
     *
     * @param {(string | number | Symbol)} identifier
     * @returns
     */
    FetchCache.prototype.get = function (identifier) {
        return this.dataHolder.get(identifier);
    };
    /**
     *	Ensures that a resource is inside the cache and the cached resource is still valid.
     *
     * @param {IdentificationData} data
     * @returns
     */
    FetchCache.prototype.ensure = function (data) {
        var _this = this;
        var identifer = this.createIdentifier(data);
        if (this.dataHolder.has(identifer)) {
            var cachedData = this.dataHolder.get(identifer);
            if (this.isCacheValid(data, cachedData)) {
                return Promise.resolve(cachedData);
            }
        }
        if (this.fetchPromises.has(identifer)) {
            return this.fetchPromises.get(identifer);
        }
        var fetchPromise = this.fetch(data);
        this.fetchPromises.set(identifer, fetchPromise);
        return fetchPromise.then(function (result) {
            _this.fetchPromises.delete(identifer);
            _this.dataHolder.set(identifer, result);
            return result;
        });
    };
    /**
     * Deletes a resource from the cache
     *
     * @param {IdentificationData} data
     */
    FetchCache.prototype.delete = function (data) {
        this.dataHolder.delete(this.createIdentifier(data));
    };
    FetchCache.makeIdentifier = function (data) {
        var type = typeof data;
        if (type === "string" || type === "number" || type === "symbol") {
            return type;
        }
        var propertyNames = Object.getOwnPropertyNames(data).sort();
        return propertyNames
            .map(function (propKey) { return propKey + "=" + data[propKey]; })
            .join("_");
    };
    return FetchCache;
}());
export { FetchCache };
