| name | mongez-reinforcements-functions |
| description | Function utilities from @mongez/reinforcements — debounce, throttle, memoize, once/after/before call-count gating, pipe/compose composition, curry/partial application, and FP primitives.
|
Function utilities
Rate-limiting, memoization, composition, currying, tiny FP primitives.
import {
debounce, throttle, memoize, once, after, before,
pipe, compose, tap, curry, partial, partialRight,
noop, identity, constant, negate, escapeRegex, attempt,
} from "@mongez/reinforcements";
Rate-limiting
debounce
debounce<T>(fn: T, wait: number, options?: {
leading?: boolean;
trailing?: boolean;
maxWait?: number;
}): Debounced<T>
type Debounced<T> = T & {
cancel(): void;
flush(): void;
pending(): boolean;
};
const save = debounce(payload => api.save(payload), 500, { maxWait: 3000 });
input.addEventListener("input", e => save(e.target.value));
button.addEventListener("click", () => save.flush());
window.addEventListener("beforeunload", () => save.cancel());
throttle
throttle<T>(fn: T, wait: number, options?: {
leading?: boolean;
trailing?: boolean;
}): Throttled<T>
type Throttled<T> = T & { cancel(): void; flush(): void; pending(): boolean };
const onScroll = throttle(() => layout(), 100);
window.addEventListener("scroll", onScroll);
Caching
memoize
memoize<T>(fn: T, options?: {
resolver?: (...args: Parameters<T>) => string;
ttl?: number;
}): Memoized<T>
type Memoized<T> = T & { clear(): void; forget(key: string): void };
const lookup = memoize((id: string) => db.users.find(id), { ttl: 60_000 });
lookup("u1");
lookup("u1");
lookup.forget(JSON.stringify(["u1"]));
lookup.clear();
Custom key:
const cached = memoize(
(a: User, b: User) => similarity(a, b),
{ resolver: (a, b) => `${a.id}-${b.id}` },
);
Call-count gating
once<T>(fn: T): T
after<T>(n: number, fn: T): (...args) => R | undefined
before<T>(n: number, fn: T): (...args) => R | undefined
const init = once(() => expensiveSetup());
init(); init(); init();
const onAllDone = after(3, () => render());
onAllDone(); onAllDone(); onAllDone();
const tryConnect = before(3, () => connect());
Composition
pipe / compose
pipe<A>(value: A): A
pipe<A, B>(value: A, fn1: (a: A) => B): B
pipe<A, B, C>(value: A, fn1: (a: A) => B, fn2: (b: B) => C): C
compose<A, B, C>(fn2: (b: B) => C, fn1: (a: A) => B): (a: A) => C
pipe(2, n => n + 1, n => n * 10);
const shout = compose(
(s: string) => s + "!",
(s: string) => s.toUpperCase(),
);
shout("hi");
tap / tap.with
tap<T>(value: T, sideEffect: (value: T) => void): T
tap.with<T>(sideEffect: (value: T) => void): (value: T) => T
Side-effect probe. tap.with returns a pipeline-friendly identity-with-side-effect.
pipe(value, trim, tap.with(console.log), toSnakeCase);
Currying & partial application
curry(fn: (...args) => R): any
partial<T>(fn: T, ...preset): (...rest) => ReturnType<T>
partialRight<T>(fn: T, ...preset): (...rest) => ReturnType<T>
const add = curry((a: number, b: number, c: number) => a + b + c);
add(1)(2)(3);
add(1, 2)(3);
add(1, 2, 3);
const greet = (greeting: string, name: string) => `${greeting}, ${name}`;
const hello = partial(greet, "Hello");
hello("Ada");
const divide = (a: number, b: number) => a / b;
const halve = partialRight(divide, 2);
halve(10);
Tiny FP primitives
noop(): void
identity<T>(value: T): T
constant<T>(value: T): () => T
negate<T>(predicate: T): (...args) => boolean
items.filter(identity);
events.on("data", noop);
const always42 = constant(42);
const isOdd = negate((n: number) => n % 2 === 0);
escapeRegex
escapeRegex(string: string): string
Escape regex meta-characters so a literal string can be used in a RegExp.
new RegExp(escapeRegex("a.b+c"));
attempt
attempt<T, F = undefined>(fn: () => Promise<T>, fallback?: F): Promise<T | F>
attempt<T, F = undefined>(fn: () => T, fallback?: F): T | F
Run fn and return its result; if it throws or rejects, return fallback (or undefined). Works for sync and async functions — a promise-returning fn yields a promise. Removes one-off try/catch boilerplate.
const config = attempt(() => JSON.parse(raw), {});
const user = await attempt(() => api.getUser(id), null);