decorio
Version:
First-class ECMAScript decorators for caching, binding, and concurrency patterns
49 lines (48 loc) • 1.75 kB
TypeScript
type DebouncedDecorator = {
<A extends Array<unknown>, R extends Promise<unknown> | void>(value: unknown, context: ClassMethodDecoratorContext<object, (...args: A) => R>): (...args: A) => R;
<A extends Array<unknown>, R extends Promise<unknown> | void>(value: unknown, context: ClassFieldDecoratorContext<object, (...args: A) => R>): (originalFn: (...args: A) => R) => (...args: A) => R;
};
/**
* 🎯 Creates a decorator that debounces method calls by `delayMs` milliseconds.
*
* Each burst of calls within the delay window collapses into a single invocation.
* All returned Promises resolve (or reject) with the result of that single, last call.
*
* ⚠️ Ignores all arguments when deciding what to cancel: every new call, regardless of its parameters,
* will abort whatever was running before.
*
* Usage:
* ```typescript
* class Searcher {
* @debounced(300) async search(query: string): Promise<Array<string>> { ... }
* }
*
* const s = new Searcher();
* s.search('a');
* s.search('ab');
* s.search('abc'); // only this one triggers after 300ms
* ```
*
* Usage with debounced.signal:
* ```typescript
* class Fetcher {
* @debounced(500) async fetchData(id: string): Promise<object> {
* const { signal } = debounced;
*
* // Pass the signal to fetch so that prior calls get aborted
* return fetch(`/api/data/${id}`, { signal }).then((r) => r.json());
* }
* }
*
* const f = new Fetcher();
* f.fetchData('foo');
* f.fetchData('bar');
* ```
*
* @param delayMs how long to wait (ms) after the last call before executing
*/
export declare function debounced(delayMs: number): DebouncedDecorator;
export declare namespace debounced {
var signal: AbortSignal | undefined;
}
export {};