From 343447c37cffe8bafc841c6c439ba9e0412044ad Mon Sep 17 00:00:00 2001 From: apt-get Date: Sat, 5 Sep 2026 03:27:39 +0200 Subject: [PATCH] delete done parts during assembly to prevent needing double the stream size as available disk space --- src/lib/streamCache.svelte.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/lib/streamCache.svelte.ts b/src/lib/streamCache.svelte.ts index 6c4af5a..d9be581 100644 --- a/src/lib/streamCache.svelte.ts +++ b/src/lib/streamCache.svelte.ts @@ -67,8 +67,6 @@ export async function download(stream: StreamSummary) { export async function remove(streamId: string) { cached.delete(streamId); await discard(streamId); - const root = await navigator.storage.getDirectory(); - await root.removeEntry(streamId).catch(() => {}); } export async function getUrl(streamId: string): Promise { @@ -140,10 +138,15 @@ async function assemble(streamId: string, total: number) { const root = await navigator.storage.getDirectory(); const dir = await partsDir(streamId, true); const handle = await root.getFileHandle(streamId, { create: true }); - const writable = await handle.createWritable(); + + // track size from previous assembling attempt if there was one + const done = (await handle.getFile()).size; + + const writable = await handle.createWritable({ keepExistingData: done > 0 }); + await writable.seek(done); // check at each step the chunk names (ranges) are coherent - let written = 0; + let written = done; while (written < total) { const name = String(written); const part = await dir.getFileHandle(name).catch(() => null); @@ -156,7 +159,8 @@ async function assemble(streamId: string, total: number) { } await writable.close(); - await discard(streamId); + partials.delete(streamId); + await sweep(streamId); // chunks went missing, shit's fucked... if (written !== total) throw new Error(`Assembled ${written} of ${total} bytes`); } @@ -168,9 +172,11 @@ async function partsDir(streamId: string, create = false) { return parts.getDirectoryHandle(streamId, { create }); } -/** discard stream's partial download state and run a sweep of leftover parts files */ +/** discard everything on disk for a stream that is not fully downloaded */ async function discard(streamId: string) { partials.delete(streamId); + const root = await navigator.storage.getDirectory(); + await root.removeEntry(streamId).catch(() => {}); await sweep(streamId); }