before
Creates a function that allows the given callback to be called only before it reaches the specified number of invocations. Includes a .reset()
method to restart the call count.
1/**
2 * Creates a function that allows the given callback to be called
3 * only before it reaches the specified number of invocations.
4 * Includes a .reset() method to restart the call count.
5 *
6 * @param count - Max number of allowed calls before blocking the callback.
7 * @param fn - The function to call before the threshold is reached.
8 * @returns A function with a reset() method.
9 */
10export function before(count: number, fn: () => void): (() => void) & { reset: () => void } {
11 let calls = 0;
12
13 const wrapper = () => {
14 if (calls < count) {
15 fn();
16 }
17 calls++;
18 };
19
20 wrapper.reset = () => {
21 calls = 0;
22 };
23
24 return wrapper;
25}
Call-Limiting Logic
Restricts the execution of a function to a maximum number of times, preventing overuse or redundant calls.
Stateful Internal Tracking
Maintains its own call count, eliminating the need for external control mechanisms.
Resettable for Reuse
Provides a
.reset()
method to restart the internal state, allowing the logic to be reused in multiple cycles.Simple and Reliable
Clear, side-effect-free logic ensures predictable behavior, useful in both sync and async contexts.
Tests | Examples
1test('before - allows callback only before specified count', () => {
2 const spy = jest.fn();
3 const fn = before(3, spy);
4
5 fn(); // 1
6 fn(); // 2
7 fn(); // 3 (not triggered, already reached)
8 fn(); // 4
9 expect(spy).toHaveBeenCalledTimes(2); // Only first 2 calls work
10});
11
12test('before - reset() restarts the counter', () => {
13 const spy = jest.fn();
14 const fn = before(2, spy);
15
16 fn(); // 1
17 fn(); // 2
18 expect(spy).toHaveBeenCalledTimes(1); // Only first call works
19
20 fn.reset();
21
22 fn(); // 1 again
23 fn(); // 2 again
24 expect(spy).toHaveBeenCalledTimes(2); // One more after reset
25});
26
27test('before - does nothing if count is 0 or less', () => {
28 const spy = jest.fn();
29 const fn = before(0, spy);
30
31 fn();
32 fn();
33 expect(spy).not.toHaveBeenCalled();
34});
Common Use Cases
One-Time Setup with Limited Retries
Limit how many times a setup or fallback logic runs (e.g., polling attempts, toast notifications).
UI or Animation Triggers
Trigger visual effects, alerts, or transitions a limited number of times (e.g., only on the first few interactions).
Performance Safeguards
Prevent expensive operations from being triggered repeatedly after a defined threshold.
Form or Input Restrictions
Allow user actions (like resending a code or retrying a login) only a certain number of times before locking.
Testing and Debug Tools
Temporarily allow a block of logic to run for a fixed number of times to simulate or measure behavior.