Skip to content

Commit 8a9619c

Browse files
fix: replace NodeJS.Timeout with ReturnType<typeof setTimeout> for better compatibility
1 parent 6fa5b2c commit 8a9619c

File tree

1 file changed

+62
-126
lines changed
  • packages/components/src/ui/data-table-filter/lib

1 file changed

+62
-126
lines changed
Lines changed: 62 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,138 +1,74 @@
1-
type ControlFunctions = {
2-
cancel: () => void
3-
flush: () => void
4-
isPending: () => boolean
5-
}
6-
7-
type DebounceOptions = {
8-
leading?: boolean
9-
trailing?: boolean
10-
maxWait?: number
11-
}
12-
1+
/**
2+
* Debounce function for handling user input
3+
* @param fn Function to debounce
4+
* @param delay Delay in milliseconds
5+
* @returns Debounced function
6+
*/
137
export function debounce<T extends (...args: any[]) => any>(
14-
func: T,
15-
wait: number,
16-
options: DebounceOptions = {},
17-
): ((...args: Parameters<T>) => ReturnType<T> | undefined) & ControlFunctions {
18-
const { leading = false, trailing = true, maxWait } = options
19-
let timeout: NodeJS.Timeout | null = null
20-
let lastArgs: Parameters<T> | null = null
21-
let lastThis: any
22-
let result: ReturnType<T> | undefined
23-
let lastCallTime: number | null = null
24-
let lastInvokeTime = 0
25-
26-
const maxWaitTime = maxWait !== undefined ? Math.max(wait, maxWait) : null
27-
28-
function invokeFunc(time: number): ReturnType<T> | undefined {
29-
if (lastArgs === null) return undefined
30-
const args = lastArgs
31-
const thisArg = lastThis
32-
lastArgs = null
33-
lastThis = null
34-
lastInvokeTime = time
35-
result = func.apply(thisArg, args)
36-
return result
37-
}
38-
39-
function shouldInvoke(time: number): boolean {
40-
if (lastCallTime === null) return false
41-
const timeSinceLastCall = time - lastCallTime
42-
const timeSinceLastInvoke = time - lastInvokeTime
43-
return (
44-
lastCallTime === null ||
45-
timeSinceLastCall >= wait ||
46-
timeSinceLastCall < 0 ||
47-
(maxWaitTime !== null && timeSinceLastInvoke >= maxWaitTime)
48-
)
49-
}
50-
51-
function startTimer(
52-
pendingFunc: () => void,
53-
waitTime: number,
54-
): NodeJS.Timeout {
55-
return setTimeout(pendingFunc, waitTime)
56-
}
57-
58-
function remainingWait(time: number): number {
59-
if (lastCallTime === null) return wait
60-
const timeSinceLastCall = time - lastCallTime
61-
const timeSinceLastInvoke = time - lastInvokeTime
62-
const timeWaiting = wait - timeSinceLastCall
63-
return maxWaitTime !== null
64-
? Math.min(timeWaiting, maxWaitTime - timeSinceLastInvoke)
65-
: timeWaiting
66-
}
67-
68-
function timerExpired() {
69-
const time = Date.now()
70-
if (shouldInvoke(time)) {
71-
return trailingEdge(time)
8+
fn: T,
9+
delay: number
10+
): (...args: Parameters<T>) => void {
11+
/**
12+
* Timeout ID for the debounced function
13+
* Using ReturnType<typeof setTimeout> instead of NodeJS.Timeout for better compatibility
14+
*/
15+
let timeout: ReturnType<typeof setTimeout> | null = null
16+
17+
/**
18+
* Debounced function
19+
* @param args Arguments to pass to the original function
20+
*/
21+
return function (this: any, ...args: Parameters<T>): void {
22+
const context = this
23+
24+
if (timeout) {
25+
clearTimeout(timeout)
7226
}
73-
timeout = startTimer(timerExpired, remainingWait(time))
74-
}
7527

76-
function leadingEdge(time: number): ReturnType<T> | undefined {
77-
lastInvokeTime = time
78-
timeout = startTimer(timerExpired, wait)
79-
return leading ? invokeFunc(time) : undefined
80-
}
81-
82-
function trailingEdge(time: number): ReturnType<T> | undefined {
83-
timeout = null
84-
if (trailing && lastArgs) {
85-
return invokeFunc(time)
86-
}
87-
lastArgs = null
88-
lastThis = null
89-
return result
28+
timeout = setTimeout(() => {
29+
fn.apply(context, args)
30+
timeout = null
31+
}, delay)
9032
}
33+
}
9134

92-
function debounced(
35+
/**
36+
* Debounce function that returns a promise
37+
* @param fn Function to debounce
38+
* @param delay Delay in milliseconds
39+
* @returns Debounced function that returns a promise
40+
*/
41+
export function debouncePromise<T extends (...args: any[]) => Promise<any>>(
42+
fn: T,
43+
delay: number
44+
): (...args: Parameters<T>) => Promise<ReturnType<T>> {
45+
/**
46+
* Timeout ID for the debounced function
47+
* Using ReturnType<typeof setTimeout> instead of NodeJS.Timeout for better compatibility
48+
*/
49+
let timeout: ReturnType<typeof setTimeout> | null = null
50+
51+
/**
52+
* Debounced function that returns a promise
53+
* @param args Arguments to pass to the original function
54+
* @returns Promise that resolves with the result of the original function
55+
*/
56+
return function (
9357
this: any,
9458
...args: Parameters<T>
95-
): ReturnType<T> | undefined {
96-
const time = Date.now()
97-
const isInvoking = shouldInvoke(time)
98-
99-
lastArgs = args
100-
lastThis = this
101-
lastCallTime = time
59+
): ReturnType<typeof setTimeout> {
60+
const context = this
10261

103-
if (isInvoking) {
104-
if (timeout === null) {
105-
return leadingEdge(lastCallTime)
62+
return new Promise((resolve) => {
63+
if (timeout) {
64+
clearTimeout(timeout)
10665
}
107-
if (maxWaitTime !== null) {
108-
timeout = startTimer(timerExpired, wait)
109-
return invokeFunc(lastCallTime)
110-
}
111-
}
112-
if (timeout === null) {
113-
timeout = startTimer(timerExpired, wait)
114-
}
115-
return result
116-
}
11766

118-
debounced.cancel = () => {
119-
if (timeout !== null) {
120-
clearTimeout(timeout)
121-
}
122-
lastInvokeTime = 0
123-
lastArgs = null
124-
lastThis = null
125-
lastCallTime = null
126-
timeout = null
127-
}
128-
129-
debounced.flush = () => {
130-
return timeout === null ? result : trailingEdge(Date.now())
67+
timeout = setTimeout(() => {
68+
resolve(fn.apply(context, args))
69+
timeout = null
70+
}, delay)
71+
}) as unknown as ReturnType<typeof setTimeout>
13172
}
132-
133-
debounced.isPending = () => {
134-
return timeout !== null
135-
}
136-
137-
return debounced
13873
}
74+

0 commit comments

Comments
 (0)