Stream decrypted downloads to disk with bounded memory (closes #40)
check / check (push) Successful in 23s
check / check (push) Successful in 23s
Originals no longer buffer the whole decrypted file in RAM. `streamDecrypt` writes each secretstream chunk to the staged temp file as it is pulled and returns the byte count, so peak memory is one chunk, not the file size. The temp-then-rename fsync discipline of the exported `writeAtomic` is factored into a shared helper that both the whole-buffer path and the streaming path use. The rename still happens only after the stream authenticates on `TAG_FINAL`; a truncated or corrupt stream throws and removes the temp file, leaving the destination untouched as before. Because the plaintext is no longer buffered, the atomic write moved inside the retry: each attempt streams from byte zero into its own temp file and only a complete attempt renames. Closes #21. Model: opus-4-8
This commit is contained in:
@@ -18,6 +18,17 @@ Update the README API reference section to match the current implementation.
|
||||
|
||||
# Completed Steps
|
||||
|
||||
- 2026-09-22: Streamed decrypted downloads straight to disk instead of buffering
|
||||
a whole file in memory (issue 40, subsumes issue 21).
|
||||
`downloadFile`/`downloadThumbnail` write each secretstream chunk to the temp
|
||||
file as it is decrypted and rename into place only after the stream
|
||||
authenticates on `TAG_FINAL`, so peak memory is bounded by the 4 MiB chunk
|
||||
size rather than the file size. Because the plaintext is no longer buffered,
|
||||
the atomic write moved inside the retry: each attempt stages its own temp file
|
||||
from byte zero and only a complete attempt renames, so a truncated stream
|
||||
still leaves no destination file and a retry replaces the temp cleanly.
|
||||
`writeAtomic` stays exported for small whole-buffer payloads (thumbnails,
|
||||
metadata) via a shared temp-then-rename helper.
|
||||
- 2026-09-22: Added resumable, deletion-aware enumeration to `Client` (issue 38,
|
||||
closes issue 7). `collectionsSince`/`filesSince` take a starting cursor,
|
||||
decrypt live records, surface tombstoned ids in a separate `deleted` list (a
|
||||
|
||||
Reference in New Issue
Block a user