lib/jsdom/living/helpers/mutation-observers.js
function queueMutationRecord(
  type,
  target,
  name,
  namespace,
  oldValue,
  addedNodes,
  removedNodes,
  previousSibling,
  nextSibling
) {
  const interestedObservers = new Map();

  const nodes = domSymbolTree.ancestorsToArray(target);

  for (const node of nodes) {
    for (const registered of node._registeredObserverList) {
      const { options, observer: mo } = registered;

      if (
        !(node !== target && options.subtree === false) &&
        !(type === MUTATION_TYPE.ATTRIBUTES && options.attributes !== true) &&
        !(type === MUTATION_TYPE.ATTRIBUTES && options.attributeFilter &&
          !options.attributeFilter.some(value => value === name || value === namespace)) &&
        !(type === MUTATION_TYPE.CHARACTER_DATA && options.characterData !== true) &&
        !(type === MUTATION_TYPE.CHILD_LIST && options.childList === false)
      ) {
        if (!interestedObservers.has(mo)) {
          interestedObservers.set(mo, null);
        }

        if (
          (type === MUTATION_TYPE.ATTRIBUTES && options.attributeOldValue === true) ||
          (type === MUTATION_TYPE.CHARACTER_DATA && options.characterDataOldValue === true)
        ) {
          interestedObservers.set(mo, oldValue);
        }
      }
    }
  }

  for (const [observer, mappedOldValue] of interestedObservers.entries()) {
    const record = MutationRecord.createImpl([], {
      type,
      target,
      attributeName: name,
      attributeNamespace: namespace,
      oldValue: mappedOldValue,
      addedNodes,
      removedNodes,
      previousSibling,
      nextSibling
    });

    observer._recordQueue.push(record);
    activeMutationObservers.add(observer);
  }

  queueMutationObserverMicrotask();
}
function queueMutationRecord(
  type,
  target,
  name,
  namespace,
  oldValue,
  addedNodes,
  removedNodes,
  previousSibling,
  nextSibling
) {
  const interestedObservers = new Map();

  const nodes = domSymbolTree.ancestorsToArray(target);

  for (const node of nodes) {
    for (const registered of node._registeredObserverList) {
      const { options, observer: mo } = registered;

      if (
        !(node !== target && options.subtree === false) &&
        !(type === MUTATION_TYPE.ATTRIBUTES && options.attributes !== true) &&
        !(type === MUTATION_TYPE.ATTRIBUTES && options.attributeFilter &&
          !options.attributeFilter.some(value => value === name || value === namespace)) &&
        !(type === MUTATION_TYPE.CHARACTER_DATA && options.characterData !== true) &&
        !(type === MUTATION_TYPE.CHILD_LIST && options.childList === false)
      ) {
        if (!interestedObservers.has(mo)) {
          interestedObservers.set(mo, null);
        }

        if (
          (type === MUTATION_TYPE.ATTRIBUTES && options.attributeOldValue === true) ||
          (type === MUTATION_TYPE.CHARACTER_DATA && options.characterDataOldValue === true)
        ) {
          interestedObservers.set(mo, oldValue);
        }
      }
    }
  }

  for (const [observer, mappedOldValue] of interestedObservers.entries()) {
    const record = MutationRecord.createImpl([], {
      type,
      target,
      attributeName: name,
      attributeNamespace: namespace,
      oldValue: mappedOldValue,
      addedNodes,
      removedNodes,
      previousSibling,
      nextSibling
    });

    observer._recordQueue.push(record);
    activeMutationObservers.add(observer);
  }

  queueMutationObserverMicrotask();
}
https://dom.spec.whatwg.org/#queue-a-mutation-record