import type { AnyAsyncFunction, AnyFunction } from '../types.js' import type { AsyncDebounceOptions, AsyncThrottleOptions, DebounceOptions, ThrottleOptions, } from './debounce.js' import { _asyncDebounce, _asyncThrottle, _debounce, _throttle } from './debounce.js' import type { MethodDecorator } from './decorator.util.js' export function _Debounce( wait: number, opt: DebounceOptions = {}, ): MethodDecorator { return (_target, _key, descriptor) => { const originalFn = descriptor.value! descriptor.value = _debounce(originalFn, wait, opt) return descriptor } } export function _Throttle( wait: number, opt: ThrottleOptions = {}, ): MethodDecorator { return (_target, _key, descriptor) => { const originalFn = descriptor.value! descriptor.value = _throttle(originalFn, wait, opt) return descriptor } } /** * Like `@_Debounce`, but for async methods: every call returns a real Promise resolving with the * coalesced invocation's result, so `await`-ing never yields a stale value or a non-promise * * Be aware that the decorated method may resolve `undefined` if the config yields no invocation, * which the method's `T` type can't express. * * @experimental */ export function _AsyncDebounce( wait: number, opt: AsyncDebounceOptions = {}, ): MethodDecorator { return (_target, _key, descriptor) => { const originalFn = descriptor.value! descriptor.value = _asyncDebounce(originalFn, wait, opt) as any return descriptor } } /** * Like `@_Throttle`, but for async methods. * * @see {@link _AsyncDebounce} * * @experimental */ export function _AsyncThrottle( wait: number, opt: AsyncThrottleOptions = {}, ): MethodDecorator { return (_target, _key, descriptor) => { const originalFn = descriptor.value! descriptor.value = _asyncThrottle(originalFn, wait, opt) as any return descriptor } }