-
v1.6.31 Stable
released this
2026-03-05 00:45:46 +01:00 | 41 commits to main since this releasev1.6.31 — Massive Stability & Infrastructure Update
This release consolidates 8 rounds of deep code review (108 bug fixes across the entire codebase) plus a full infrastructure migration to a self-hosted Gitea instance.
Infrastructure
- Migrated primary release and auto-update source from Codeberg to
git.24-music.de(self-hosted Gitea) - Added multi-source update fallback chain: git.24-music.de → Codeberg → GitHub
- New one-command release script:
npm run release:gitea -- <version> "<notes>" - App renamed to "Multi Debrid Downloader"
Download Engine (download-manager.ts)
- Fixed session byte tracking corruption:
resolveStartConflictoverwrite path used raw.delete()instead ofdropItemContribution(), permanently inflatingtotalDownloadedBytesand corrupting speed/ETA display - Fixed start() race condition: Set
session.running = truebefore firstawaitto prevent concurrentstart()calls from bypassing the guard - Fixed item-recovery race: Added post-await re-check of item status and active tasks to prevent overwriting an active download with "completed"
- Fixed done-phase marking failed archives as "Done": Both hybrid and final extraction done handlers now only clear tracking maps instead of blindly marking all remaining archives as completed
- Fixed extraction triggered on disabled packages at startup:
recoverPostProcessingOnStartupnow respectspkg.enabled - Fixed stream.destroy() leak: Moved
stream.destroy()into catch block before re-throwing to prevent file handle leaks on Windows - Fixed prepareForShutdown mislabeling: Pending/waiting extraction items no longer get incorrectly labeled as "abgebrochen"
- Fixed stop() missing retryStateByItem.clear(): Stale retry counters from previous runs no longer accumulate
- Fixed stop() pkg.enabled label: Items in disabled packages now show "Paket gestoppt" instead of "Wartet"
- Fixed missing retryStateByItem.clear() in empty start() path: Prevents stale retry counters from causing premature item shelving
- Fixed resolveStartConflict not resetting item.provider: Provider field no longer shows stale data after overwrite
- Fixed normalizeSessionStatuses for disabled packages: Items in disabled packages now show "Paket gestoppt" after restart instead of "Wartet"
- Fixed startPackages/startItems skipping triggerPendingExtractions: "Start Selected" on fully-downloaded-but-unextracted packages now correctly triggers extraction
- Fixed missing releaseTargetPath in tiny-file detection: Reserved target path slot is now released when a tiny error-response file is detected and deleted
- Fixed hybrid extraction abort not checking session.running: Abort path now uses
session.runningin status ternary, consistent with all other paths - Fixed timeout branch updatedAt on already-extracted items:
updatedAtis now only stamped whenfullStatusactually changes - Fixed hybrid extraction progress callback churning updatedAt: Added
entry.fullStatus !== labelguard to prevent unnecessary persistence pressure every 260ms - Fixed updatedAt set unconditionally in 3 extraction error/abort handlers: Now only set when fullStatus actually changes
- Fixed reorderPackages O(n²): Changed
valid.includes(id)toseen.has(id)for Set-based lookup - Fixed duplicate retryAfterByItem/retryStateByItem.clear() in clearAll(): Removed redundant double-clear
- Fixed indentation inconsistency in start() method
- Improved importBackup persistence protection: New
blockAllPersistenceflag blocks bothpersistSoon()and shutdown persistence to protect restored backups from being overwritten by in-flight async saves - Various extraction status label fixes, progress sorting, and status transition corrections across R1-R5
Extractor (extractor.ts)
- Fixed noextractor:skipped unhandled throw: Password-discovery serial pass now catches non-abort errors properly instead of propagating unhandled out of
extractPackageArchives - Fixed nested archive namespace collision: Added
nested:prefix to resume state keys for nested archives to prevent false resume matches with original archives - Fixed hasAnyEntries false positive on empty directories: Uses recursive file check (
hasAnyFilesRecursive) instead of directory-entry check - Fixed SevenZipJBinding "registered codecs" error: JVM extractor now falls back to legacy UnRAR instead of throwing
- Fixed parallel JVM extraction temp dir conflicts: Each JVM process gets an isolated temp directory to prevent native DLL file lock crashes
Debrid Service (debrid.ts, realdebrid.ts)
- Fixed sleepWithSignal race condition: Added
signal.abortedcheck before entering Promise constructor to prevent missed abort signals - Fixed dead ternary branch in MegaDebridClient.unrestrictLink: Simplified unreachable
web ?arm that always evaluated to false branch - Fixed HTML response detection: Properly handles cases where Real-Debrid returns HTML instead of JSON
Storage (storage.ts)
- Fixed orphaned temp files on non-EXDEV rename failure: Both
writeSettingsPayloadandwriteSessionPayloadnow clean up temp files before re-throwing rename errors
UI (App.tsx)
- Fixed progress bar overflow:
dlProgress,exProgress, andcombinedProgressare now clamped to their respective maxima (50/100) to prevent CSS overflow when progress data briefly exceeds 100% - Fixed BandwidthChart resize handler: Previous pending
requestAnimationFrameis now cancelled before scheduling a new one during resize bursts - Fixed extractHoster called twice per render: Item-row hoster column now computes the value once
- Fixed delete confirm dialog negative totalRemaining: Uses
Math.max(0, ...)to prevent display of negative item counts - Fixed dead CSS selector in Escape key handler: Removed non-existent
.link-popup-overlayclass reference - Fixed collapsedPackages missing from auto-expand useEffect deps: Auto-expand logic now correctly reacts to collapse state changes
- Deduplicated Hoster/Account column IIFE calculations: Eliminated redundant computation in package header rendering
Full list of reviewed files
Every line of the following files was reviewed across 8 rounds with 10 parallel review agents each:
src/main/download-manager.ts(7,070 lines)src/main/extractor.ts(2,332 lines)src/main/debrid.ts(1,127 lines)src/main/realdebrid.ts(202 lines)src/main/storage.ts(728 lines)src/main/app-controller.ts(366 lines)src/main/main.ts(513 lines)src/renderer/App.tsx(3,475 lines)
Downloads
- Migrated primary release and auto-update source from Codeberg to