diff --git a/.changeset/humble-coats-shop.md b/.changeset/humble-coats-shop.md new file mode 100644 index 000000000..d41bcaf07 --- /dev/null +++ b/.changeset/humble-coats-shop.md @@ -0,0 +1,5 @@ +--- +'@tanstack/pacer': patch +--- + +Fixed a bug in AsyncDebouncer where getAbortSignal() incorrectly returned null due to an internal execution ID mismatch. Abort signals can now be properly attached to underlying async tasks. diff --git a/packages/pacer/src/async-debouncer.ts b/packages/pacer/src/async-debouncer.ts index d24d721a7..faf13db0b 100644 --- a/packages/pacer/src/async-debouncer.ts +++ b/packages/pacer/src/async-debouncer.ts @@ -362,7 +362,7 @@ export class AsyncDebouncer { ...args: Parameters ): Promise | undefined> => { if (!this.#getEnabled()) return undefined - const currentMaybeExecuteCount = this.store.state.maybeExecuteCount + 1 + const currentMaybeExecuteCount = this.store.state.maybeExecuteCount try { this.#setState({ isExecuting: true }) diff --git a/packages/pacer/tests/async-debouncer.test.ts b/packages/pacer/tests/async-debouncer.test.ts index 66ac0ca99..a5f6a31c9 100644 --- a/packages/pacer/tests/async-debouncer.test.ts +++ b/packages/pacer/tests/async-debouncer.test.ts @@ -1,4 +1,4 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { afterEach, beforeEach, describe, expect, it, vi, } from 'vitest' import { AsyncDebouncer, asyncDebounce } from '../src/async-debouncer' describe('AsyncDebouncer', () => { @@ -1358,5 +1358,27 @@ describe('asyncDebounce helper function', () => { expect(typeof debouncer.getAbortSignal).toBe('function') expect(debouncer.getAbortSignal()).toBeNull() }) + + + it('should return an AbortSignal and mark it aborted when abort() is called', async () => { + const debouncer = new AsyncDebouncer( + async () => { + const signal = debouncer.getAbortSignal() + expect(signal).toBeInstanceOf(AbortSignal) + expect(signal?.aborted).toBe(false) + return 'result' + }, + { wait: 300 }, + ) + + + debouncer.maybeExecute() + vi.advanceTimersByTime(150) + const promise = debouncer.maybeExecute() + vi.advanceTimersByTime(300) + debouncer.abort() + expect(debouncer.getAbortSignal()?.aborted ?? true).toBe(true) + await promise + }) }) })