You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Persist Jack download progress in SQLite so a future Jack UI/API can show active, completed, and failed downloads without scraping logs or scanning folders.
Motivation
The blackhole flow cannot report native progress back to Radarr/Sonarr, and Jack currently only emits progress as logs while the HTTP stream is active. A Jack UI needs a first-class download state source.
Proposed Scope
Add a SQLite-backed download registry using bun:sqlite.
Do not create a progress row immediately after parsing the .torrent stub. Stub parsing only gives torrentFilename, peerId, and itemId, which is not enough for a useful download record.
Create the download progress row after BlackholeWatcher.processTorrent() successfully resolves peer.getRelease(itemId), when Jack knows the media filename, destination path, part path, and release metadata.
Store one row per actual peer file download with fields like:
torrentFilename
peerId / peerName
itemId
filename
destPath / partPath
releaseSize from peer release metadata, for early display before the file response starts
expectedBytes, nullable until the peer file response headers are received
downloadedBytes
status (downloading, completed, failed, import_queued)
startedAt, updatedAt, completedAt
error
Metadata lookup failures before a progress row exists should still be logged with torrentFilename, peerId, and itemId; they do not need to appear as download progress records unless a separate event/audit table is added later.
Set releaseSize when the row is created from peer.getRelease(itemId).
Set authoritative expectedBytes when PeerConnector.downloadFile() receives the peer file response:
For full downloads, use the Content-Length header from GET /peer/items/:id/file.
If Content-Length is missing or invalid, keep expectedBytes null and expose indeterminate progress, or fail explicitly if the download path requires known length.
If Content-Length differs from releaseSize, store/log the mismatch; the response header is authoritative for the active transfer.
Reporting progress inside Radarr/Sonarr. That would require Jack to implement a real supported download-client API shim instead of the current Torrent Blackhole flow.
Summary
Persist Jack download progress in SQLite so a future Jack UI/API can show active, completed, and failed downloads without scraping logs or scanning folders.
Motivation
The blackhole flow cannot report native progress back to Radarr/Sonarr, and Jack currently only emits progress as logs while the HTTP stream is active. A Jack UI needs a first-class download state source.
Proposed Scope
bun:sqlite..torrentstub. Stub parsing only givestorrentFilename,peerId, anditemId, which is not enough for a useful download record.BlackholeWatcher.processTorrent()successfully resolvespeer.getRelease(itemId), when Jack knows the media filename, destination path, part path, and release metadata.torrentFilenamepeerId/peerNameitemIdfilenamedestPath/partPathreleaseSizefrom peer release metadata, for early display before the file response startsexpectedBytes, nullable until the peer file response headers are receiveddownloadedBytesstatus(downloading,completed,failed,import_queued)startedAt,updatedAt,completedAterrortorrentFilename,peerId, anditemId; they do not need to appear as download progress records unless a separate event/audit table is added later.releaseSizewhen the row is created frompeer.getRelease(itemId).expectedByteswhenPeerConnector.downloadFile()receives the peer file response:Content-Lengthheader fromGET /peer/items/:id/file.Content-Lengthis missing or invalid, keepexpectedBytesnull and expose indeterminate progress, or fail explicitly if the download path requires known length.Content-Lengthdiffers fromreleaseSize, store/log the mismatch; the response header is authoritative for the active transfer.Content-Rangeon206 Partial Contentresponses.PeerConnector.downloadFile()to accept a progress callback or state updater instead of only logging progress.GET /downloadsandGET /downloads/:id.downloadingrows, using.partfile size when available and marking unrecoverable rows as failed/stale.Acceptance Criteria
expectedBytessource is clear and covered by tests for normal, missing, and mismatched response length cases.Out of Scope