Download Manager
Overview
Built-in download manager for the Electron application, similar to a web browser's download UI. Allows users to track, resume, and manage their file and anchoring proof downloads.
Replaces the legacy system that loaded entire files into RAM (silent crash above ~100MB).
How it works
Backend architecture (main process):
manager.mjsorchestrates downloads via PQueue (max 3 concurrent)handlers/http.mjshandles HTTP streaming with retry (3 attempts, backoff 1s/2s/4s) and resume via Range headershandlers/local.mjshandles streaming copy for local storagepersistence.mjssaves/loads history with 30-day retentionutils.mjsresolves file paths without conflicts (automatic incremental naming)
Frontend architecture (renderer):
- Dedicated Redux store (
store/downloads/) synchronized via IPC events - UI components in
src/components/DownloadManager/ useDownloadListenershook initialized inGlobalEffectsProvider
Features
- Real-time progress tracking with visual progress bars
- Modern dropdown UI showing active and completed downloads
- Automatic file naming with incremental numbering (file.pdf → file (1).pdf)
- Download queue management (max 3 concurrent)
- Persistent download history (30-day retention, user-scoped)
- Automatic retry on network failures (3 attempts with exponential backoff)
- Resume interrupted downloads from last byte (Range headers for Azure, GCP, SharePoint)
- File existence verification with visual indication (strikethrough for deleted files)
- Click-to-open files and show in folder
- Auto-open panel on completion
- Error display with full message on hover and copy-to-clipboard
- Type tag ("file" / "proof") to distinguish download types
- Archive files (zip, tar, rar) open containing folder instead of file
- Cross-platform path conversion for Local storage (Windows ↔ Mac)
Azure Blob Storage — SAS Token Handling
Since v4.35.0, the download manager supports a new Azure config format where the SAS token is separated from the container URL:
- New format:
containerUrl+sasToken(separate fields) — token renewal only requires config update, no document migration - Old format: remote URL contains the full SAS token — still supported for backward compatibility
- Detection is automatic: presence of
?in the remote URL distinguishes old vs new format - Upload stores filename only when using the new config format
@deprecated v4.35.0 markers added to old format code paths for future cleanup.
Key files
main/downloads/manager.mjs— Orchestration, IPC handlers, queuemain/downloads/handlers/http.mjs— HTTP streaming, retry, resumemain/downloads/handlers/local.mjs— Local streaming copymain/downloads/persistence.mjs— Per-user persistent historymain/downloads/utils.mjs— Path resolution, incremental namingsrc/store/downloads/— Redux store (actions, reducer, selectors, types)src/components/DownloadManager/— UI (dropdown, progress bars, states)src/utils/downloadHelpers.ts— Config builders for all storage targets, Azure SAS token URL constructionsrc/components/SidebarTabs/Details.tsx— Sidebar integration (file size, download button)src/services/fileProtect/uploadHandlers/azureBlob.pipe.ts— Azure upload with new config format support
Technical decisions
- Streaming in main process rather than renderer: avoids renderer process RAM limits, isolates network I/O in a dedicated process.
- Electron
net.requestrather thanfetch: native support for enterprise OS-level proxies. - PQueue to limit to 3 concurrent downloads: tradeoff between speed and network/disk load.
.partfiles during download: enables resume and prevents serving incomplete files.- Per-user history (
userData/downloads-history/{userId}.json): each user only sees their own downloads. - 30-day retention: prevents history from growing indefinitely.
- Separate SAS token from container URL (Azure): enables token renewal without document migration, backward compatible with existing documents.
Known issues
- BCYIP server does not support Range headers → resume fails, download restarts from 0 (see
docs/backend-range-support.md) - Archives (zip, tar, rar) open containing folder instead of file (intended for file downloads, not for proofs)
Next steps
- Backend Range header support for BCYIP server
- Batch download (multi-select)