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 | 1x 1x 8x 8x 8x 8x 8x 9x 1x 1x 1x 1x 1x 1x 1x 1x 8x 8x 8x 8x 29x 29x 29x 29x 5x 5x 29x 1x 1x 1x 8x 8x 9x 8x 8x 8x 8x 8x 8x 8x 8x 8x | import { captureStack } from '../exception.js'; export type LoopFn = (fn: () => void) => Promise<number>; export type StopFn = () => void; export type MicroLooper = [LoopFn, StopFn]; /** * Creates a micro loop that executes a function repeatedly with a fixed time delay. * Each iteration is executed asynchronously and the loop continues until the maximum number of iterations is reached. * * @param timeout - The interval in milliseconds between each execution * @param steps - The maximum number of iterations to execute * @returns A tuple containing the loop function and stop function */ export function microloop(timeout: number, steps: number): MicroLooper { let isRunning = false; let currentStep = 0; let currentInterval = 0; let currentResolver: ((value: number) => void) | undefined = undefined; const loop = (fn: () => void) => { if (isRunning) { captureStack.warning.external( 'Duplicated loop detected:', 'Attempted to run a looper with a running looper.', 'Multi loop not allowed', loop ); return Promise.resolve(0); } isRunning = true; return new Promise<number>((resolve) => { currentResolver = resolve; currentInterval = setInterval(() => { currentStep++; try { fn(); if (currentStep >= steps) { stop(); } } catch (error) { captureStack.error.external('Walker execution failed.', error as Error); stop(); } }, timeout) as never; }); }; const stop = () => { clearInterval(currentInterval); currentResolver?.(currentStep); isRunning = false; currentStep = 0; currentInterval = 0; }; return [loop, stop]; } |