All files / core/src/utils push.ts

100% Statements 27/27
100% Branches 9/9
100% Functions 4/4
100% Lines 27/27

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 541x                                           1x 11x   11x 16x 1x 1x 1x 1x   15x   15x 16x 7x 7x 7x 1x 7x 7x 7x 7x 16x 16x   11x 4x 4x   11x 11x  
import { captureStack } from '../exception.js';
 
export type PushHandler = () => void;
export type PushFn = () => void;
export type Pusher = (fn: PushHandler) => PushFn;
export type PushResetter = () => void;
export type MicroPusher = [Pusher, PushResetter];
 
/**
 * Creates a micro push system that allows registering and executing a single handler function.
 *
 * @returns A tuple containing:
 *   - push: A function that registers a handler and returns an exec function
 *   - clear: A function that clears the currently registered handler
 *
 * The push function registers a handler that can be executed once through the returned exec function.
 * If a new handler is registered, the previous one is replaced.
 * The clear function removes the current handler, making it unable to be executed.
 *
 * This is useful for situations where you have multiple async operations that need to perform an identical final
 * operation such as set the loading state to false after all operations have completed.
 */
export function micropush(): MicroPusher {
  let handle: PushHandler | undefined;
 
  const push: Pusher = (fn: PushHandler) => {
    if (typeof fn !== 'function') {
      const error = new Error('Invalid argument.');
      captureStack.error.argument('The given argument is not a function.', error, push);
      return () => {};
    }
 
    handle = fn;
 
    return () => {
      if (handle === fn) {
        try {
          handle();
        } catch (error) {
          captureStack.error.external('Push execution failed.', error as Error);
        } finally {
          handle = undefined;
        }
      }
    };
  };
 
  const clear = () => {
    handle = undefined;
  };
 
  return [push, clear] as const;
}