Content dedup on both sides, stored checksums, spool-free zips, upload stats
ci / docker (push) Successful in 12s

- sha256+crc32 hashed during upload streaming; unique index per album
- duplicate content returns the existing photo (race-safe via 23505)
- client hashes locally (WebCrypto) and skips the transfer entirely for
  content the album already has
- zip downloads stream S3->response directly using the stored crc32;
  pre-hash photos spool once and self-heal (crc via zip, sha via reprocess)
- upload UI: overall progress bar, bytes, live speed, ETA
This commit is contained in:
2026-07-17 14:41:07 +02:00
parent a6819809a7
commit 6259ca84d8
11 changed files with 296 additions and 60 deletions
+7
View File
@@ -73,6 +73,13 @@ export function postDownload(url, ids = '') {
form.remove()
}
// SHA-256 of a File, matching the server's content hash — used to skip
// uploading bytes the album already has.
export async function sha256Hex(file) {
const digest = await crypto.subtle.digest('SHA-256', await file.arrayBuffer())
return [...new Uint8Array(digest)].map((b) => b.toString(16).padStart(2, '0')).join('')
}
export function uploadFile(url, file, onProgress) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()