| 700 | * @returns The debounced function. |
| 701 | */ |
| 702 | export const debounce = <T extends (...args: Parameters<T>) => ReturnType<T>>( |
| 703 | debouncedFunction: T, |
| 704 | wait: number = 500, |
| 705 | opts: { immediate?: boolean | number } = {}, |
| 706 | ): ((...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>>) => { |
| 707 | let timeout: NodeJS.Timeout | null = null; |
| 708 | let isFirstCall = true; |
| 709 | const immediateMs = |
| 710 | (typeof opts.immediate === 'number' && opts.immediate >= 0) || opts.immediate === true |
| 711 | ? Number(opts.immediate) |
| 712 | : false; |
| 713 | |
| 714 | return (...args: Parameters<T>): Promise<Awaited<ReturnType<T>>> => { |
| 715 | const waitMs = isFirstCall && immediateMs !== false ? immediateMs : wait; |
| 716 | isFirstCall = false; |
| 717 | |
| 718 | return new Promise((resolve, reject) => { |
| 719 | if (timeout) { |
| 720 | clearTimeout(timeout); |
| 721 | } |
| 722 | |
| 723 | timeout = setTimeout(() => { |
| 724 | try { |
| 725 | const result = debouncedFunction(...args); |
| 726 | |
| 727 | return Promise.resolve(result).then(resolve).catch(reject); |
| 728 | } catch (error) { |
| 729 | reject(error); |
| 730 | } |
| 731 | }, waitMs); |
| 732 | }); |
| 733 | }; |
| 734 | }; |