1. /**
    
  2.  * Copyright (c) Meta Platforms, Inc. and affiliates.
    
  3.  *
    
  4.  * This source code is licensed under the MIT license found in the
    
  5.  * LICENSE file in the root directory of this source tree.
    
  6.  * @flow
    
  7.  */
    
  8. 
    
  9. import {rethrowCaughtError} from 'shared/ReactErrorUtils';
    
  10. 
    
  11. import type {ReactSyntheticEvent} from './ReactSyntheticEventType';
    
  12. import accumulateInto from './accumulateInto';
    
  13. import forEachAccumulated from './forEachAccumulated';
    
  14. import {executeDispatchesInOrder} from './EventPluginUtils';
    
  15. 
    
  16. /**
    
  17.  * Internal queue of events that have accumulated their dispatches and are
    
  18.  * waiting to have their dispatches executed.
    
  19.  */
    
  20. let eventQueue: ?(Array<ReactSyntheticEvent> | ReactSyntheticEvent) = null;
    
  21. 
    
  22. /**
    
  23.  * Dispatches an event and releases it back into the pool, unless persistent.
    
  24.  *
    
  25.  * @param {?object} event Synthetic event to be dispatched.
    
  26.  * @private
    
  27.  */
    
  28. function executeDispatchesAndRelease(event: ReactSyntheticEvent) {
    
  29.   if (event) {
    
  30.     executeDispatchesInOrder(event);
    
  31. 
    
  32.     if (!event.isPersistent()) {
    
  33.       event.constructor.release(event);
    
  34.     }
    
  35.   }
    
  36. }
    
  37. // $FlowFixMe[missing-local-annot]
    
  38. function executeDispatchesAndReleaseTopLevel(e) {
    
  39.   return executeDispatchesAndRelease(e);
    
  40. }
    
  41. 
    
  42. export function runEventsInBatch(
    
  43.   events: Array<ReactSyntheticEvent> | ReactSyntheticEvent | null,
    
  44. ) {
    
  45.   if (events !== null) {
    
  46.     eventQueue = accumulateInto(eventQueue, events);
    
  47.   }
    
  48. 
    
  49.   // Set `eventQueue` to null before processing it so that we can tell if more
    
  50.   // events get enqueued while processing.
    
  51.   const processingEventQueue = eventQueue;
    
  52.   eventQueue = null;
    
  53. 
    
  54.   if (!processingEventQueue) {
    
  55.     return;
    
  56.   }
    
  57. 
    
  58.   forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);
    
  59. 
    
  60.   if (eventQueue) {
    
  61.     throw new Error(
    
  62.       'processEventQueue(): Additional events were enqueued while processing ' +
    
  63.         'an event queue. Support for this has not yet been implemented.',
    
  64.     );
    
  65.   }
    
  66. 
    
  67.   // This would be a good time to rethrow if any of the event handlers threw.
    
  68.   rethrowCaughtError();
    
  69. }