function extractEvents(
  dispatchQueue: DispatchQueue,
  domEventName: DOMEventName,
  targetInst: null | Fiber,
  nativeEvent: AnyNativeEvent,
  nativeEventTarget: null | EventTarget,
  eventSystemFlags: EventSystemFlags,
  targetContainer: null | EventTarget,
) {
  if (!enableScrollEndPolyfill) {
    return;
  }

  const inCapturePhase = (eventSystemFlags & IS_CAPTURE_PHASE) !== 0;

  if (domEventName !== 'scrollend') {
    if (!isScrollEndEventSupported && inCapturePhase) {
      switch (domEventName) {
        case 'scroll': {
          if (nativeEventTarget !== null) {
            debounceScrollEnd(targetInst, nativeEvent, nativeEventTarget);
          }
          break;
        }
        case 'touchstart': {
          isTouchStarted = true;
          break;
        }
        case 'touchcancel':
        case 'touchend': {
          // Note we cannot use pointer events for this because they get
          // cancelled when native scrolling takes control.
          isTouchStarted = false;
          break;
        }
        case 'mousedown': {
          isMouseDown = true;
          break;
        }
        case 'mouseup': {
          isMouseDown = false;
          break;
        }
      }
    }
    return;
  }

  if (!isScrollEndEventSupported && nativeEventTarget !== null) {
    const existingTimer = getScrollEndTimer(nativeEventTarget);
    if (existingTimer != null) {
      // If we do get a native scrollend event fired, we cancel the polyfill.
      // This could happen if our feature detection is broken or if there's another
      // polyfill calling dispatchEvent to fire it before we fire ours.
      clearTimeout(existingTimer);
      clearScrollEndTimer(nativeEventTarget);
    } else {
      // If we didn't receive a 'scroll' event first, we ignore this event to avoid
      // double firing. Such as if we fired our onScrollEnd polyfill and then
      // we also observed a native one afterwards.
      return;
    }
  }

  // In React onScrollEnd doesn't bubble.
  const accumulateTargetOnly = !inCapturePhase;

  const listeners = accumulateSinglePhaseListeners(
    targetInst,
    'onScrollEnd',
    'scrollend',
    inCapturePhase,
    accumulateTargetOnly,
    nativeEvent,
  );

  if (listeners.length > 0) {
    // Intentionally create event lazily.
    const event: ReactSyntheticEvent = new SyntheticUIEvent(
      'onScrollEnd',
      'scrollend',
      null,
      nativeEvent,
      nativeEventTarget,
    );
    dispatchQueue.push({event, listeners});
  }
}
This plugin creates an `onScrollEnd` event polyfill when the native one
is not available.