async function waitOnEventOrTimeout({ target, name, delay = 0 }) {
  if (
    typeof target !== "object" ||
    !(name && typeof name === "string") ||
    !(Number.isInteger(delay) && delay >= 0)
  ) {
    throw new Error("waitOnEventOrTimeout - invalid parameters.");
  }
  const { promise, resolve } = Promise.withResolvers();
  const ac = new AbortController();

  function handler(type) {
    ac.abort(); // Remove event listener.
    clearTimeout(timeout);

    resolve(type);
  }

  const evtMethod = target instanceof EventBus ? "_on" : "addEventListener";
  target[evtMethod](name, handler.bind(null, WaitOnType.EVENT), {
    signal: ac.signal,
  });

  const timeout = setTimeout(handler.bind(null, WaitOnType.TIMEOUT), delay);

  return promise;
}
Allows waiting for an event or a timeout, whichever occurs first.
Can be used to ensure that an action always occurs, even when an event
arrives late or not at all.

@param {WaitOnEventOrTimeoutParameters}
@returns {Promise} A promise that is resolved with a {WaitOnType} value.