import { isSome } from "@jet/environment";
import { Wrapper } from "./wrapper";
/**
 * A bag wrapper that implements caching. All accessed values are cached until this object is reinitialized via rebootstrap or recreated.
 *
 */
export class CachedBag extends Wrapper {
    constructor() {
        super(...arguments);
        /**
         * A cache of entries
         *
         * Note that `Opt<T>` values which are nil are stored, representing that the bag has no value for a key, which
         * is coalesced in the JS. This prevents infinite cache misses when the bag has no value for a key, resulting in
         * unnecessary calls to the native client
         */
        this.cache = {};
    }
    registerBagKeys(keys) {
        this.implementation.registerBagKeys(keys);
    }
    string(key, forceDisableCache = false) {
        return this.fromCache(key, forceDisableCache, () => {
            return this.implementation.string(key);
        });
    }
    double(key, forceDisableCache = false) {
        return this.fromCache(key, forceDisableCache, () => {
            return this.implementation.double(key);
        });
    }
    integer(key, forceDisableCache = false) {
        return this.fromCache(key, forceDisableCache, () => {
            return this.implementation.integer(key);
        });
    }
    boolean(key, forceDisableCache = false) {
        return this.fromCache(key, forceDisableCache, () => {
            return this.implementation.boolean(key);
        });
    }
    array(key, forceDisableCache = false) {
        return this.fromCache(key, forceDisableCache, () => {
            return this.implementation.array(key);
        });
    }
    dictionary(key, forceDisableCache = false) {
        return this.fromCache(key, forceDisableCache, () => {
            return this.implementation.dictionary(key);
        });
    }
    url(key, forceDisableCache = false) {
        return this.fromCache(key, forceDisableCache, () => {
            return this.implementation.url(key);
        });
    }
    /**
     * Returns a cached value if possible to do so, otherwise uses the closure to fetch a new value which is cached and returned
     *
     * @param key The key on which to cache
     * @param forceDisableCache Disables the cache to ensure a fresh value from the bag
     * @param fetchValue A closure to fetch new values with
     * @returns A previously or newly cached value
     */
    fromCache(key, forceDisableCache = false, fetchValue) {
        if (forceDisableCache) {
            return fetchValue();
        }
        else {
            const cacheEntry = this.cache[key];
            if (isSome(cacheEntry)) {
                return cacheEntry.value;
            }
            else {
                const newValue = fetchValue();
                this.cache[key] = { value: newValue };
                return newValue;
            }
        }
    }
}
//# sourceMappingURL=cached-bag.js.map