/** * Lightweight debounce for input handlers. Used by location search. * * The returned function exposes a `.cancel()` method so callers can clear a * pending invocation when the host element disconnects, preventing the timer * from firing on a detached node and mutating reactive state after teardown. */ export interface Debounced unknown> { (...args: Parameters): void; cancel: () => void; } export function debounce unknown>( fn: F, wait: number, ): Debounced { let timer: ReturnType | undefined; const debounced = ((...args: Parameters) => { if (timer) clearTimeout(timer); timer = setTimeout(() => { timer = undefined; fn(...args); }, wait); }) as Debounced; debounced.cancel = () => { if (timer) { clearTimeout(timer); timer = undefined; } }; return debounced; }