feat(m4): persist the download queue across restarts
The queue/scheduler lived only in renderer memory, so saved/scheduled and other pending downloads were silently lost on quit (audit M4). Persist them: - main: queue.ts store (proven cached-atomic createJsonStore, queue.json) + queue:list / queue:save IPC; QUEUE_MAX cap. - shared: PersistedQueueItem = the durable subset of DownloadItem (runtime-only progress/speed/eta/sizeLabel/finishing dropped). - renderer: mirror the persistable items on every queue change (a signature over the subset means progress ticks don't re-save; main's jsonStore coalesces the writes) and rehydrate on launch via an App useEffect. Pure mappers extracted to store/queuePersist.ts and unit-tested. Restore semantics: downloading -> queued (yt-dlp continues the .part), saved + scheduledFor survives so the promoter fires when due, paused/error return actionable; completed/canceled are never persisted. A queueHydrated gate stops a launch-time store change from wiping queue.json before it's read. Reconciles ROADMAP.md. typecheck + 268 tests + eslint + prettier green. (OS-level quit/relaunch cycle is worth a manual smoke test.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -31,7 +31,8 @@ import {
|
||||
type ScheduledSyncStatus,
|
||||
type TerminalEvent,
|
||||
type TerminalRunResult,
|
||||
type TaskbarProgress
|
||||
type TaskbarProgress,
|
||||
type PersistedQueueItem
|
||||
} from '@shared/ipc'
|
||||
|
||||
// The surface exposed to the renderer. Keep this thin: it only forwards to IPC.
|
||||
@@ -139,6 +140,13 @@ const api = {
|
||||
|
||||
clearErrorLog: (): Promise<ErrorLogEntry[]> => ipcRenderer.invoke(IpcChannels.errorLogClear),
|
||||
|
||||
/** Load the persisted download queue on launch (M4). */
|
||||
listQueue: (): Promise<PersistedQueueItem[]> => ipcRenderer.invoke(IpcChannels.queueList),
|
||||
|
||||
/** Mirror the renderer's durable queue items to disk so they survive a quit (M4). */
|
||||
saveQueue: (items: PersistedQueueItem[]): Promise<void> =>
|
||||
ipcRenderer.invoke(IpcChannels.queueSave, items),
|
||||
|
||||
/** Opens a save dialog and writes settings + templates to the chosen JSON file. */
|
||||
exportBackup: (): Promise<BackupExportResult> => ipcRenderer.invoke(IpcChannels.backupExport),
|
||||
|
||||
|
||||
Reference in New Issue
Block a user