dodrio 0.2.0

A fast, bump-allocated virtual DOM library.
Documentation
export function initStrace() {
  instrumentAll(Element.prototype);
  instrumentAll(Document.prototype);
  instrumentAll(Node.prototype);
  instrumentAll(EventTarget.prototype);
}

const counts = new Map;
counts.total = 0;

let timer = null;

function log(ctorName, kind, key) {
  counts.total += 1;

  const entry = `${kind} ${ctorName}#${key}`
  const count = counts.get(entry);
  if (count === undefined) {
    counts.set(entry, 1);
  } else {
    counts.set(entry, count + 1);
  }

  if (timer !== null) {
    clearTimeout(timer);
  }
  timer = setTimeout(dumpAndReset, 100);
}

function dumpAndReset() {
  const data = [...counts]
        .sort((a, b) => b[1] - a[1])
        .map(a => ({ "DOM Method": a[0], "Count": a[1] }));

  data.push({ "DOM Method": "<total>", "Count": counts.total });

  console.table(data, ["DOM Method", "Count"]);

  counts.clear();
  counts.total = 0;
}

function instrument(proto, key, desc) {
  const ctorName = proto.constructor.name;

  if (typeof desc.value == "function") {
    const f = desc.value;
    desc.value = function (...args) {
      log(ctorName, "call", key);
      return f.apply(this, args);
    };
  }

  if (typeof desc.get == "function") {
    const get = desc.get;
    desc.get = function (...args) {
      log(ctorName, "get", key);
      return get.apply(this, args);
    };
  }

  if (typeof desc.set == "function") {
    const set = desc.set;
    desc.set = function (...args) {
      log(ctorName, "set", key);
      return set.apply(this, args);
    };
  }

  Object.defineProperty(proto, key, desc);
}

function instrumentAll(proto) {
  for (const key of Object.keys(proto)) {
    const desc = Object.getOwnPropertyDescriptor(proto, key);
    if (desc.configurable) {
      instrument(proto, key, desc);
    }
  }
}