fix(search): runSearch bricht pending Debounce ab
All checks were successful
Build & Publish Docker Image / build-and-push (push) Successful in 1m20s
All checks were successful
Build & Publish Docker Image / build-and-push (push) Successful in 1m20s
Enter waehrend Debounce-Fenster feuerte bislang eine zweite Fetch fuer dieselbe Query. Race-Guard greift nicht, weil q identisch ist. runSearch clearTimeout am Anfang behebt's, neuer Unit-Test sichert es. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -73,6 +73,8 @@ export class SearchStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async runSearch(q: string): Promise<void> {
|
async runSearch(q: string): Promise<void> {
|
||||||
|
if (this.debounceTimer) clearTimeout(this.debounceTimer);
|
||||||
|
this.debounceTimer = null;
|
||||||
this.localExhausted = false;
|
this.localExhausted = false;
|
||||||
this.webPageno = 0;
|
this.webPageno = 0;
|
||||||
this.webExhausted = false;
|
this.webExhausted = false;
|
||||||
|
|||||||
@@ -221,6 +221,22 @@ describe('SearchStore', () => {
|
|||||||
expect(fetchImpl.mock.calls[1][0]).toMatch(/&domains=chefkoch\.de/);
|
expect(fetchImpl.mock.calls[1][0]).toMatch(/&domains=chefkoch\.de/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('runSearch(q) cancels pending debounce to avoid double-fetch', async () => {
|
||||||
|
vi.useFakeTimers();
|
||||||
|
const fetchImpl = mockFetch([
|
||||||
|
{ body: { hits: [{ id: 1, title: 'immediate', description: null, image_path: null, source_domain: null, avg_stars: null, last_cooked_at: null }] } }
|
||||||
|
]);
|
||||||
|
const store = new SearchStore({ fetchImpl, debounceMs: 300 });
|
||||||
|
store.query = 'meal';
|
||||||
|
store.runDebounced(); // schedules the 300ms timer
|
||||||
|
// Before the timer fires, call runSearch immediately (e.g. form submit).
|
||||||
|
await store.runSearch('meal');
|
||||||
|
expect(fetchImpl).toHaveBeenCalledTimes(1);
|
||||||
|
// Now advance past the original debounce — timer must not still fire.
|
||||||
|
await vi.advanceTimersByTimeAsync(400);
|
||||||
|
expect(fetchImpl).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
it('reSearch: immediate re-run with current query on filter change', async () => {
|
it('reSearch: immediate re-run with current query on filter change', async () => {
|
||||||
vi.useFakeTimers();
|
vi.useFakeTimers();
|
||||||
let filter = '';
|
let filter = '';
|
||||||
|
|||||||
Reference in New Issue
Block a user