import { assertMethodDecorator } from "../common/decorators.js"; import type { Method } from "../common/types.js"; import { isWeakMapKey } from "../common/utils.js"; export function createThrottledMethod( originalMethod: Method, delayMs: number, ): Method { let throttling = false; return function(this: This, ...args: Args): void { if (!throttling) { throttling = true; originalMethod.apply(this, args); setTimeout(() => { throttling = false; }, delayMs); } }; } export function throttle(delayMs: number) { return function( value: Method, context: ClassMethodDecoratorContext>, ): Method { assertMethodDecorator("throttle", value, context); const methodsMap = new WeakMap>(); const fallbackMethod = createThrottledMethod(value, delayMs); return function(this: This, ...args: Args): void { if (!isWeakMapKey(this)) { fallbackMethod.apply(this, args); return; } const instanceKey = this as object; if (!methodsMap.has(instanceKey)) { methodsMap.set(instanceKey, createThrottledMethod(value, delayMs)); } methodsMap.get(instanceKey)?.apply(this, args); }; }; }