• v1.6.31 ba938f64c5

    v1.6.31 Stable

    Administrator released this 2026-03-05 00:45:46 +01:00 | 41 commits to main since this release

    v1.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: resolveStartConflict overwrite path used raw .delete() instead of dropItemContribution(), permanently inflating totalDownloadedBytes and corrupting speed/ETA display
    • Fixed start() race condition: Set session.running = true before first await to prevent concurrent start() 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: recoverPostProcessingOnStartup now respects pkg.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.running in status ternary, consistent with all other paths
    • Fixed timeout branch updatedAt on already-extracted items: updatedAt is now only stamped when fullStatus actually changes
    • Fixed hybrid extraction progress callback churning updatedAt: Added entry.fullStatus !== label guard 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) to seen.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 blockAllPersistence flag blocks both persistSoon() 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.aborted check 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 writeSettingsPayload and writeSessionPayload now clean up temp files before re-throwing rename errors

    UI (App.tsx)

    • Fixed progress bar overflow: dlProgress, exProgress, and combinedProgress are now clamped to their respective maxima (50/100) to prevent CSS overflow when progress data briefly exceeds 100%
    • Fixed BandwidthChart resize handler: Previous pending requestAnimationFrame is 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-overlay class 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