constructor() {
    let readyPromiseResolver;
    let readyPromiseResolved = false;

    this.readyPromise = new Promise((resolve) => {
      readyPromiseResolver = () => {
        if (readyPromiseResolved) return;
        readyPromiseResolved = true;
        resolve();
      };
    });
    this.geometry = [];

    const computeDisplayGeometryFromConfig = (err, conf) => {
      if (err !== null) {
        return;
      }
      const geom = [];

      for (const { sourceMode, targetVideoSignalInfo, inUse } of conf) {
        if (!inUse) {
          continue;
        }

        const { width, height, position } = sourceMode;
        const { vSyncFreq } = targetVideoSignalInfo;
        // 30Hz is a safe guess for broken vSyncFreq outputs, I think...
        const vRefreshRate =
          vSyncFreq.Numerator === 0 || vSyncFreq.Denominator === 0
            ? 30
            : vSyncFreq.Numerator / vSyncFreq.Denominator;
        const top = position.y;
        const bottom = position.y + height;
        const left = position.x;
        const right = position.x + width;

        geom.push({ top, bottom, left, right, vRefreshRate });
      }

      this.geometry = geom;
      readyPromiseResolver();
    };

    this.changeListener = module.exports.addDisplayChangeListener(
      computeDisplayGeometryFromConfig
    );
  }
Establishes a context for determining the vertical refresh rate.

Active instances of this class will establish perpetual work on the event loop,
as the internals use {@link addDisplayChangeListener} to react to display changes.

In order to clear the relevant work on the Node event loop, you must call
{@link VerticalRefreshRateContext.close} when you are finished using this context.