diff --git a/apps/wing-console/packages/utilities/src/debounce.test.ts b/apps/wing-console/packages/utilities/src/debounce.test.ts new file mode 100644 index 00000000000..43fa1c9a856 --- /dev/null +++ b/apps/wing-console/packages/utilities/src/debounce.test.ts @@ -0,0 +1,24 @@ +import { afterEach, beforeEach, expect, test, vi } from "vitest"; + +import { debounce } from "./debounce.js"; + +beforeEach(() => { + vi.useFakeTimers(); +}); + +afterEach(() => { + vi.useRealTimers(); +}); + +test("debounces calls", () => { + const function_ = vi.fn(); + const debounced = debounce(function_, 1); + + debounced(); + debounced(); + debounced(); + expect(function_).toHaveBeenCalledTimes(0); + + vi.advanceTimersByTime(1); + expect(function_).toHaveBeenCalledTimes(1); +}); diff --git a/apps/wing-console/packages/utilities/src/debounce.ts b/apps/wing-console/packages/utilities/src/debounce.ts index 73286e06ae4..80cf1d4c01d 100644 --- a/apps/wing-console/packages/utilities/src/debounce.ts +++ b/apps/wing-console/packages/utilities/src/debounce.ts @@ -1,25 +1,16 @@ export function debounce void>( function_: T, wait: number, - immediate: boolean = false, ): (...arguments_: Parameters) => void { let timeout: NodeJS.Timeout | undefined; return (...arguments_: Parameters): void => { - const later = () => { - timeout = undefined; - if (!immediate) { - function_(...arguments_); - } - }; - - const callNow = immediate && !timeout; - clearTimeout(timeout); - timeout = setTimeout(later, wait); + timeout = setTimeout(() => { + timeout = undefined; - if (callNow) { + // Trailing call. function_(...arguments_); - } + }, wait); }; } diff --git a/apps/wing-console/packages/utilities/src/throttle.test.ts b/apps/wing-console/packages/utilities/src/throttle.test.ts new file mode 100644 index 00000000000..1057b044d4a --- /dev/null +++ b/apps/wing-console/packages/utilities/src/throttle.test.ts @@ -0,0 +1,39 @@ +import { afterEach, beforeEach, expect, test, vi } from "vitest"; + +import { throttle } from "./throttle.js"; + +beforeEach(() => { + vi.useFakeTimers(); +}); + +afterEach(() => { + vi.useRealTimers(); +}); + +test("throttles calls", () => { + const function_ = vi.fn(); + const throttled = throttle(function_, 100); + + throttled(); + throttled(); + throttled(); + expect(function_).toHaveBeenCalledTimes(1); + + vi.advanceTimersByTime(99); + throttled(); + throttled(); + throttled(); + expect(function_).toHaveBeenCalledTimes(1); + + vi.advanceTimersByTime(1); + throttled(); + throttled(); + throttled(); + expect(function_).toHaveBeenCalledTimes(2); + + vi.advanceTimersByTime(100); + throttled(); + throttled(); + throttled(); + expect(function_).toHaveBeenCalledTimes(3); +}); diff --git a/apps/wing-console/packages/utilities/src/throttle.ts b/apps/wing-console/packages/utilities/src/throttle.ts index a67737b962d..90e8c63e090 100644 --- a/apps/wing-console/packages/utilities/src/throttle.ts +++ b/apps/wing-console/packages/utilities/src/throttle.ts @@ -2,10 +2,10 @@ export function throttle void>( function_: T, timeFrame: number, ): (...arguments_: Parameters) => void { - let lastTime = 0; + let lastTime: number | undefined; return (...arguments_) => { const now = Date.now(); - if (now - lastTime >= timeFrame) { + if (lastTime === undefined || now - lastTime >= timeFrame) { function_(...arguments_); lastTime = now; }