All files / services/utils/deepWeakMap index.ts

100% Statements 32/32
100% Branches 4/4
100% Functions 10/10
100% Lines 31/31
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 5017x 17x   624x 698x 262x   510x     17x   153x   17x 137x   17x 921x 921x 406x   921x   17x 113x   17x 436x 436x 436x   436x 436x   17x 188x 188x 262x   188x 188x   17x   17x        
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);
  }
}