All files / services/utils/deepWeakMap index.ts

100% Statements 32/32
100% Branches 4/4
100% Functions 10/10
100% Lines 31/31

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 5020x 20x   830x 912x 318x   676x     20x   180x   20x 79x   20x 1115x 1115x 550x   1115x   20x 162x   20x 594x 594x 594x   594x 594x   20x 236x 236x 318x   236x 236x   20x   20x        
import * as objectPath from 'object-path';
 
export type DeepWeakMapPath = (string | number) | (string | number)[];
 
function flattenPaths(paths: DeepWeakMapPath[]): string[] {
  return paths.reduce((accumulatedPath: string[], nextPath) => {
    if (Array.isArray(nextPath)) {
      return [...accumulatedPath, ...nextPath.map(pathPart => `${pathPart}`)];
    }
    return [...accumulatedPath, `${nextPath}`];
  }, []) as string[];
}
 
export class DeepWeakMap<
  Key extends Object,
  Value,
  Structure = { [key: string]: Value }
> {
  private map: WeakMap<Key, Structure>;
  constructor() {
    this.map = new WeakMap();
  }
 
  isEmpty(target: Key) {
    return !Object.keys(this.getAll(target)).length;
  }
 
  getAll(target: Key): Structure {
    const { map } = this;
    if (!map.has(target)) {
      map.set(target, {} as Structure);
    }
    return map.get(target);
  }
 
  set(target: Key, path: DeepWeakMapPath, value: Value) {
    objectPath.set(this.getAll(target), path, value);
  }
 
  get(target: Key, ...paths: DeepWeakMapPath[]): Value {
    const path = flattenPaths(paths);
    return objectPath.get(this.getAll(target), path);
  }
 
  has(target: Key, ...paths: DeepWeakMapPath[]): boolean {
    const path = flattenPaths(paths);
    return !!this.get(target, path);
  }
}