///
// SHA-256 файла потоком (docs/uploads.md#4): Web Crypto не умеет считать по частям, а файлы бывают по 2 ГБ —
// hash-wasm считает чанками в воркере, не держа файл в памяти и не блокируя интерфейс.
import { createSHA256 } from 'hash-wasm';
export interface HashRequest {
id: string;
file: File;
}
export type HashResponse =
| { id: string; type: 'progress'; done: number }
| { id: string; type: 'done'; sha256: string }
| { id: string; type: 'error'; message: string };
const ctx = self as unknown as DedicatedWorkerGlobalScope;
ctx.onmessage = async (e: MessageEvent) => {
const { id, file } = e.data;
try {
const h = await createSHA256();
h.init();
const reader = file.stream().getReader();
let done = 0;
let lastReport = 0;
for (;;) {
const chunk = await reader.read();
if (chunk.done) break;
h.update(chunk.value);
done += chunk.value.byteLength;
if (done - lastReport > 8 << 20) {
lastReport = done;
ctx.postMessage({ id, type: 'progress', done } satisfies HashResponse);
}
}
ctx.postMessage({ id, type: 'done', sha256: h.digest('hex') } satisfies HashResponse);
} catch (err) {
ctx.postMessage({ id, type: 'error', message: err instanceof Error ? err.message : String(err) } satisfies HashResponse);
}
};