All files / core/src/utils batch.ts

100% Statements 31/31
100% Branches 12/12
100% Functions 4/4
100% Lines 31/31

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 671x                                                         1x 9x 9x   9x 12x 16x 16x 16x 1x 1x 16x   12x 12x   9x 37x   37x 13x 12x 13x 1x 1x 13x   17x 37x   9x 1x 1x 1x   9x 9x  
import { captureStack } from '../exception.js';
 
/**
 * Type definition for a batch handler function.
 * @returns {void}
 */
export type BatchHandler = () => void;
 
/**
 * Type definition for a batch scheduler function.
 * @param {BatchHandler} fn - The function to be scheduled for batch execution.
 * @returns {void}
 */
export type BatchScheduler = (fn: BatchHandler) => void;
 
/**
 * Type definition for a batch resetter function.
 * @returns {void}
 */
export type BatchCleaner = () => void;
 
export type MicroBatch = [BatchScheduler, BatchCleaner];
 
/**
 * Creates a micro-batch scheduler that executes functions in batches after a specified delay.
 *
 * @param {number} delay - The delay in milliseconds before executing the batch. Defaults to 10ms.
 * @returns {MicroBatch} A tuple containing the scheduler and resetter functions.
 */
export function microbatch(delay: number = 10): MicroBatch {
  const BATCHES = new Set<() => void>();
  let activeId: number | undefined;
 
  const execute = () => {
    for (const handler of BATCHES) {
      try {
        handler();
      } catch (error) {
        captureStack.error.external('Batch execution failed.', error as Error);
      }
    }
 
    BATCHES.clear();
  };
 
  const schedule = (fn: () => void) => {
    if (BATCHES.has(fn)) return;
 
    if (!BATCHES.size) {
      if (delay > 0) {
        activeId = setTimeout(execute, delay) as never;
      } else {
        queueMicrotask(execute);
      }
    }
 
    BATCHES.add(fn);
  };
 
  const reset = () => {
    BATCHES.clear();
    clearTimeout(activeId);
  };
 
  return [schedule, reset];
}