All files index.ts

100% Statements 65/65
100% Branches 13/13
100% Functions 4/4
100% Lines 65/65

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 661x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 34x 34x 34x 34x 34x 34x 34x 34x 34x 34x 34x 34x 34x 4x 4x 34x 34x 34x 34x 32x 32x 24x 24x 24x 4x 4x 24x 32x 32x 34x 28x 28x 34x 4x 4x 4x 34x 34x 34x 33x 34x 1x 1x 1x 34x 1x 1x 1x 1x 1x  
import { remove, isUndefined } from "bittydash";
 
type Listener = (...args: any[]) => void;
type EventName = string | symbol;
type Options = {
  once: boolean;
};
type Subscriber = {
  listener: Listener;
  once: boolean;
};
 
const ALL_WILD_KEY = "*";
const handlerMap = new Map();
 
function subscribe(
  key: EventName,
  listener: Listener,
  options?: Options
): () => void {
  if (!handlerMap.has(key)) {
    handlerMap.set(key, []);
  }
  const list = handlerMap.get(key);
  const { once } = options || {};
  const item = { listener, once };
  list.push(item);
  return () => {
    remove(list, item);
  };
}
 
function dispatch(key: EventName, ...args: any[]) {
  const trigger = (list: Subscriber[]) => {
    const removeList = [];
    list.forEach((item: Subscriber) => {
      const { listener, once } = item;
      listener(...args);
      if (once) {
        removeList.push(item);
      }
    });
    removeList.forEach((item: Subscriber) => remove(list, item));
  };
  if (handlerMap.has(key)) {
    trigger(handlerMap.get(key));
  }
  if (key !== ALL_WILD_KEY && handlerMap.has(ALL_WILD_KEY)) {
    trigger(handlerMap.get(ALL_WILD_KEY));
  }
}
 
function clear(key?: EventName) {
  if (isUndefined(key)) {
    handlerMap.clear();
  } else {
    handlerMap.delete(key);
  }
}
 
export default {
  subscribe,
  dispatch,
  clear,
};