// LRUCache relies on the fact that Map stores keys in their insertion order.
export default class LRUCache<T> {
  private readonly maxSize: number;
  private cache: Map<string, T>;

  constructor(maxSize: number) {
    this.maxSize = maxSize;
    this.cache = new Map<string, T>();
  }

  get(key: string): T | null {
    if (!this.cache.has(key)) {
      return null;
    }

    const value = this.cache.get(key) as T;

    // Refresh key.
    this.cache.delete(key);
    this.cache.set(key, value);

    return value;
  }

  set(key: string, value: T): void {
    this.cache.delete(key);

    while (this.cache.size >= this.maxSize) {
      // Evict last used key.
      this.cache.delete(this.cache.keys().next().value!);
    }

    this.cache.set(key, value);
  }

  purge(): void {
    this.cache = new Map<string, T>();
  }
}
