Restore an evicted server copy from an online holder

This commit is contained in:
Claude
2026-09-30 07:58:42 +00:00
parent 6d3cefa874
commit 60a28fc593
8 changed files with 112 additions and 7 deletions

View File

@@ -160,7 +160,7 @@
// Send one saved video to the server so it can hash + validate it and add its
// cid to the catalog. Uploads the whole file: only on the user's request
// ("Verify & share") or when the server asks for a copy (plan 018).
async function contribute(videoId, { cid = null, title = '', channel = '' } = {}) {
async function contribute(videoId, { cid = null, title = '', channel = '', restore = false } = {}) {
const dev = await ensureDevice();
const rec = await window.DeviceDB.getFile(videoId);
const file = window.OPFS.getFileObject ? await window.OPFS.getFileObject(videoId) : null;
@@ -168,7 +168,7 @@
const h = { 'X-Device': dev.deviceId + '.' + dev.secret };
const t = await (await fetch('/api/p2p/intake', {
method: 'POST', headers: { ...h, 'Content-Type': 'application/json' },
body: JSON.stringify({ videoId, cid: cid || (rec && rec.cid) || undefined, size: file.size, title, channel }),
body: JSON.stringify({ videoId, cid: cid || (rec && rec.cid) || undefined, size: file.size, title, channel, restore }),
})).json().catch(() => ({ ok: false, error: 'server unreachable' }));
if (!t.ok || t.known) { if (t.known) changed(); return t; }
const r = await (await fetch(t.url, { method: 'PUT', headers: h, body: file }))
@@ -280,6 +280,19 @@
timer = setTimeout(sync, 5000);
}
// Plan 018: the server lost its copy and the source is gone — it asks one
// holder to send the file back. Only while sharing is on, one at a time,
// and only for the exact cid this device holds.
let restoring = false;
onMessage('upload-request', async (m) => {
if (restoring || hooks.getSettings().p2pShare === false) return;
const rec = window.DeviceDB ? await window.DeviceDB.getFile(m.videoId) : null;
if (!rec || rec.cid !== m.cid) return;
restoring = true;
try { await contribute(m.videoId, { cid: m.cid, restore: true }); } catch { /* next request retries */ }
finally { restoring = false; }
});
function start(h) {
hooks = { ...hooks, ...(h || {}) };
const idle = window.requestIdleCallback || ((fn) => setTimeout(fn, 1));