fix(downloads): harden enqueue lifecycle races

Reject superseded enqueue generations in the queue manager and coordinate frontend dispatch, pause, removal, and property mutations.
This commit is contained in:
NimBold
2026-07-10 00:04:21 +03:30
parent fbb89cde8e
commit b1c84a0fb9
13 changed files with 471 additions and 158 deletions
+27 -2
View File
@@ -1,8 +1,15 @@
import { beforeEach, describe, expect, it } from 'vitest';
import { useDownloadProgressStore } from './downloadStore';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { initDownloadListener, useDownloadProgressStore } from './downloadStore';
import * as ipc from '../ipc';
vi.mock('../ipc', () => ({
invokeCommand: vi.fn(),
listenEvent: vi.fn(),
}));
describe('useDownloadProgressStore', () => {
beforeEach(() => {
vi.clearAllMocks();
useDownloadProgressStore.setState({ progressMap: {} });
});
@@ -20,4 +27,22 @@ describe('useDownloadProgressStore', () => {
expect(useDownloadProgressStore.getState().progressMap).toEqual({});
});
it('shares listener setup across overlapping consumers and tears down after the last release', async () => {
const unlisten = vi.fn();
vi.mocked(ipc.listenEvent).mockResolvedValue(unlisten);
const first = initDownloadListener();
const second = initDownloadListener();
expect(ipc.listenEvent).toHaveBeenCalledTimes(3);
const releaseFirst = await first;
const releaseSecond = await second;
releaseFirst();
expect(unlisten).not.toHaveBeenCalled();
releaseSecond();
expect(unlisten).toHaveBeenCalledTimes(3);
});
});