All files / src/InMemoryCache InMemoryCache.ts

94.11% Statements 16/17
100% Branches 4/4
88.88% Functions 8/9
94.11% Lines 16/17

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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94  48x         48x                   112x 112x                       626x 626x 222x     404x 404x   6x     404x                   624x                       1155x                                   18x         27x         246x      
import { Seconds } from '@cardano-sdk/core';
import NodeCache from 'node-cache';
 
export type Key = string | number;
export type AsyncAction<T> = () => Promise<T>;
 
export class InMemoryCache {
  protected cache: NodeCache;
  protected ttlDefault: number;
 
  /**
   *
   * @param ttl The default time to live in seconds
   * @param cache The cache engine. It must extend NodeCache
   */
  constructor(ttl: Seconds | 0, cache: NodeCache = new NodeCache()) {
    this.ttlDefault = ttl;
    this.cache = cache;
  }
 
  /**
   * Get a cached key value, if not found execute db query and cache the result with that key
   *
   * @param key Cache key
   * @param asyncAction Async function to get the value
   * @param ttl The time to live in seconds
   * @returns The value stored with the key
   */
  public async get<T>(key: Key, asyncAction: AsyncAction<T>, ttl = this.ttlDefault): Promise<T> {
    const cachedValue: T | undefined = this.cache.get(key);
    if (cachedValue) {
      return cachedValue;
    }
 
    const resultPromise = asyncAction();
    this.set(
      key,
      resultPromise.catch(() => this.cache.del(key)),
      ttl
    );
    return resultPromise;
  }
 
  /**
   * Get a cached key
   *
   * @param key Cache key
   * @returns The value stored in the key
   */
  public getVal<T>(key: Key) {
    return this.cache.get<T>(key);
  }
 
  /**
   * Set a cached key
   *
   * @param key Cache key
   * @param value A value to cache
   * @param ttl The time to live in seconds
   * @returns The success state of the operation
   */
  public set<T>(key: Key, value: T, ttl = this.ttlDefault) {
    return this.cache.set<T>(key, value, ttl);
  }
 
  /**
   * Invalidate cached values
   *
   * @param keys cache key to delete or a array of cache keys
   */
  public invalidate(keys: Key | Key[]) {
    this.cache.del(keys);
  }
 
  /**
   * List all keys within this cache
   *
   * @returns An array of all keys
   */
  public keys() {
    return this.cache.keys();
  }
 
  /** Clear the interval timeout which is set on check period option. Default: 600 */
  public shutdown() {
    this.cache.close();
  }
 
  /** Clear the whole data and reset the stats */
  public clear() {
    this.cache.flushAll();
  }
}