"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AsyncQueue = void 0;
const assert_never_1 = require("./assert-never");
class AsyncQueue {
    constructor(create) {
        this.create = create;
        this.cache = new Map();
    }
    set(key, value) {
        this.cache.set(key, { type: 'done', result: value });
    }
    preload(key) {
        this.get(key).catch(() => {
            return;
        });
    }
    get(key) {
        const cache = this.cache.get(key);
        if (cache) {
            if (cache.type === 'pending') {
                return cache.promise;
            }
            else if (cache.type === 'done') {
                return Promise.resolve(cache.result);
            }
            else {
                return (0, assert_never_1.assertNever)(cache);
            }
        }
        const promise = this.create(key)
            .then((result) => {
            this.cache.set(key, { type: 'done', result });
            return result;
        })
            .catch((error) => {
            this.cache.delete(key);
            throw error;
        });
        this.cache.set(key, { type: 'pending', promise });
        return promise;
    }
}
exports.AsyncQueue = AsyncQueue;
class AsyncCache {
    constructor(create) {
        this.create = create;
        this.cache = new Map();
    }
    set(key, value) {
        this.cache.set(key, { type: 'done', result: value });
    }
    preload(key) {
        this.get(key).catch(() => {
            return;
        });
    }
    get(key) {
        const cache = this.cache.get(key);
        if (cache) {
            if (cache.type === 'pending') {
                return cache.promise;
            }
            else if (cache.type === 'done') {
                return Promise.resolve(cache.result);
            }
            else {
                return (0, assert_never_1.assertNever)(cache);
            }
        }
        const promise = this.create(key)
            .then((result) => {
            this.cache.set(key, { type: 'done', result });
            return result;
        })
            .catch((error) => {
            this.cache.delete(key);
            throw error;
        });
        this.cache.set(key, { type: 'pending', promise });
        return promise;
    }
}
exports.default = AsyncCache;
//# sourceMappingURL=async-cache.js.map