All files mutex.ts

100% Statements 18/18
100% Branches 6/6
100% Functions 5/5
100% Lines 16/16

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  1x 1x 1x             7x 7x 2x 2x 12x     5x 5x 21x 21x 6x 21x 6x 21x      
import {codeMutex} from './codeMutex';
 
/* tslint:disable no-invalid-this */
 
/**
 * Executes only one instance of give code at a time. For parallel calls, it
 * returns the result of the ongoing execution.
 */
export function mutex<This, Args extends any[], Return>(
  fn: (this: This, ...args: Args) => Promise<Return>,
  context?: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Promise<Return>>,
) {
  const isDecorator = !!context;
  if (!isDecorator) {
    const mut = codeMutex<Return>();
    return async function (this: This, ...args: Args): Promise<Return> {
      return await mut(async () => await fn.call(this, ...args));
    };
  }
  const instances = new WeakMap<any, WeakMap<any, any>>();
  return async function (this: This, ...args: Args): Promise<Return> {
    let map = instances.get(this);
    if (!map) instances.set(this, (map = new WeakMap<any, any>()));
    if (!map.has(fn)) map.set(fn, codeMutex<Return>());
    return await map.get(fn)!(async () => await fn.call(this, ...args));
  };
}