electron/cloud-sync-plan.mjs
Rama main · réplica de lectura del repositorio original.
// What one pass of Files does, worked out from three listings of one folder: this computer's (`pc`), My Cloud's
// (`cloud`) and the base (each file as it was when both last matched). Pure: the engine carries the plan out.
// This many files leaving a shared folder at once, and at least this share of it, waits for the person to say so.
export const ASK_DELETES_AT = 10;
export const ASK_DELETES_SHARE = 0.2;
/**
* A shared folder goes one way, this computer to My Cloud: this computer's version always wins. A file gone from this
* computer is removed from My Cloud only when the base proves it was there, and never while anything else cannot be read
* (`unsettled`, or `kept`: links and hard-linked files, present but not carried). Files only My Cloud has (a bot's) stay.
*/
export function planShare({ base, pc, cloud, keptDirs = [] }) {
const uploads = [], records = [], deletes = [], forgets = [];
const underKept = (path) => keptDirs.some((dir) => path.startsWith(`${dir}/`));
for (const [path, file] of pc) {
if (file.unsettled || file.kept) continue;
const there = cloud.get(path);
if (there?.sha256 === file.sha256) {
const known = base.get(path);
if (!known || known.sha256 !== file.sha256 || known.size !== file.size || known.mtimeMs !== file.mtimeMs) records.push({ path, sha256: file.sha256, size: file.size, mtimeMs: file.mtimeMs });
continue;
}
uploads.push({ path, sha256: file.sha256, size: file.size, mtimeMs: file.mtimeMs, file: file.file, baseSha256: there?.sha256 ?? null });
}
for (const [path, known] of base) {
if (pc.has(path) || underKept(path)) continue;
const there = cloud.get(path);
if (!there) { forgets.push({ path }); continue; }
deletes.push({ path, baseSha256: there.sha256, size: known.size });
}
const ask = deletes.length > 0 && ((pc.size === 0 && base.size > 0) || (deletes.length >= ASK_DELETES_AT && deletes.length >= ASK_DELETES_SHARE * base.size));
return { uploads, records, deletes, forgets, ask };
}
/**
* A bot's work comes one way, My Cloud to this computer, and never deletes here. A file the person changed here since it
* came (size or time differs from the base) is kept as it is: My Cloud's newer version lands beside it (`beside`). A file
* the person removed here comes back only when My Cloud has a newer version.
*/
export function planOutputs({ base, pc, cloud }) {
const downloads = [], records = [];
for (const [path, there] of cloud) {
const here = pc.get(path), known = base.get(path);
if (here?.unsettled || here?.kept) continue;
if (here && here.sha256 === there.sha256) {
if (!known || known.sha256 !== there.sha256 || known.size !== here.size || known.mtimeMs !== here.mtimeMs) records.push({ path, sha256: there.sha256, size: here.size, mtimeMs: here.mtimeMs });
continue;
}
if (known && known.sha256 === there.sha256) continue;
if (!here) { downloads.push({ path, sha256: there.sha256, size: there.size, replace: null }); continue; }
const untouched = Boolean(known && here.size === known.size && here.mtimeMs === known.mtimeMs);
downloads.push({ path, sha256: there.sha256, size: there.size, replace: untouched ? here : null, beside: !untouched });
}
return { downloads, records };
}