storebound/apps/desktop/src/lib/progress.ts

18 lines
1.3 KiB
TypeScript

// Progress from the command's own lines, so a job toast shows a real bar while an upload runs: `apple upload` prints
// "still uploading, 4m30s, 312/890 MB (35%), part 4/12" (cli/lib/progress.ts share()), part lines "part 3/12", and
// render / capture lines "[12/48]" or "12/48". Pure; null when a line says nothing about progress.
export interface LineProgress { done: number; total: number }
export function progressOf(line: string): LineProgress | null {
const mb = /(\d+(?:\.\d+)?)\s*\/\s*(\d+(?:\.\d+)?)\s*MB\b/.exec(line);
if (mb) { const done = Number(mb[1]), total = Number(mb[2]); if (total > 0 && done <= total) return { done: Math.round(done * 1048576), total: Math.round(total * 1048576) }; }
const pct = /\((\d{1,3})%\)/.exec(line);
if (pct && Number(pct[1]) <= 100) return { done: Number(pct[1]), total: 100 };
const part = /\b(?:part|item|image|shot|frame)s?\s+(\d+)\s*\/\s*(\d+)\b/i.exec(line) ?? /\[(\d+)\s*\/\s*(\d+)\]/.exec(line);
if (part) { const done = Number(part[1]), total = Number(part[2]); if (total > 0 && done <= total) return { done, total }; }
return null;
}
/** The last lines of a job, kept for its toast's log (newest last, at most `max`). */
export const keepLines = (lines: string[] | undefined, line: string, max = 40): string[] => [...(lines ?? []), line].slice(-max);