froebel
Version:
TypeScript utility library
39 lines (36 loc) • 1.21 kB
JavaScript
import { assert } from "./except.mjs";
/**
* Returns a version of the function `fun` that can only be invoked `limit`
* times.
* An optional `except` function will be called with the same parameters on any
* additional invocations.
*
* If `fun` returns anything but `void` (or `Promise<void>`), supplying an
* `except` function is mandatory.
*
* The `except` function must have the same return type as `fun`, or — if `fun`
* returns a promise — it may return the type that the promise resolves to
* synchronously.
*
* The `except` function may also throw instead of returning a value.
*/
export const limitInvocations = (fun, limit, ...[except]) => {
assert(limit >= 1, "limit must be >= 1", RangeError);
let invs = 0;
return (...args) => {
if (invs < limit) {
invs++;
return fun(...args);
}
if (typeof except === "function") return except(...args);
};
};
/**
* Special case of {@link limitInvocations}. `fun` can only be invoked once.
*
* @see {@link limitInvocations}
*/
export const once = (fun, ...[except]) => {
let invs = 0;
return (...args) => ++invs > 1 ? except === null || except === void 0 ? void 0 : except(...args) : fun(...args);
};