Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 1x 1x 1x 1x 1x 1x 3x 3x 3x 1x 1x 2x 2x 1x 1x 2x 2x 1x 1x | /**
 * Prevents creating multiple promises for a single key.
 *
 * If an existing promise for a key is pending, that promise will be returned without
 * creating a new one.
 *
 * If a promise throws an error, it will be discarded, and a new one created the next
 * time a key is requested.
 *
 * For now it only supports primitive value keys, but we can extend it if necessary.
 */
export class PromiseCache<Key extends string | number | undefined, Result> {
    constructor(private createPromiseFromKey: (key: Key) => Promise<Result>) {}
 
    private promisesByKey = new Map<Key, Promise<Result>>()
 
    get(key: Key): Promise<Result> {
        if (!this.promisesByKey.has(key)) {
            this.promisesByKey.set(
                key,
                // Make sure to attach .catch() _before_ adding it to the cache.
                // Otherwise external logic would be able to attach a catch() that
                // could make this one unreachable.
                this.createPromiseFromKey(key).catch((error) => {
                    this.promisesByKey.delete(key)
                    throw error
                })
            )
        }
        return this.promisesByKey.get(key)!
    }
 
    has(key: Key): boolean {
        return this.promisesByKey.has(key)
    }
}
  |