UNPKG

fast-md5-web

Version:

A TypeScript project with tsup bundler for Rust WASM MD5 calculation

131 lines (129 loc) 3.33 kB
"use client" // src/md5-worker.ts import WasmInit, { Md5Calculator } from "../wasm/pkg"; var calculator = null; var sharedMemoryView = null; var streamStates = /* @__PURE__ */ new Map(); self.onmessage = async function(e) { const { id, type, data } = e.data; if (type === "init_shared_memory") { if (data?.sharedMemory) { sharedMemoryView = new Uint8Array(data.sharedMemory); } return; } if (type === "calculate") { try { if (!calculator) { await WasmInit(); calculator = new Md5Calculator(); } if (data?.isStreamMode) { await initializeStreamProcessing(id, data); } else { await processNormalFile(id, data); } } catch (error) { streamStates.delete(id); self.postMessage({ id, type: "error", data: { error: error.message } }); } } if (type === "calculate_chunk") { try { await processChunk(id, data); } catch (error) { streamStates.delete(id); self.postMessage({ id, type: "error", data: { error: error.message } }); } } }; async function initializeStreamProcessing(id, data) { if (!calculator) { await WasmInit(); calculator = new Md5Calculator(); } const hasher = new Md5Calculator(); hasher.start_incremental_md5(id); streamStates.set(id, { hasher, processedChunks: 0, totalChunks: data.totalChunks || 1, totalSize: data.dataLength || 0, processedSize: 0 }); } async function processChunk(id, data) { const state = streamStates.get(id); if (!state) { throw new Error("Stream state not found"); } let chunkData; if (data?.dataOffset !== void 0 && data?.dataLength !== void 0 && sharedMemoryView) { chunkData = sharedMemoryView.slice( data.dataOffset, data.dataOffset + data.dataLength ); } else if (data?.chunkData) { chunkData = new Uint8Array(data.chunkData); } else { throw new Error("No valid chunk data provided"); } const updateSuccess = state.hasher.update_incremental_md5(id, chunkData); if (!updateSuccess) { throw new Error("Failed to update incremental MD5"); } state.processedChunks++; state.processedSize += chunkData.length; const progress = state.processedChunks / state.totalChunks * 100; self.postMessage({ id, type: "progress", data: { progress } }); if (state.processedChunks >= state.totalChunks) { const result = state.hasher.finalize_incremental_md5( id, data.md5Length || 32 ); streamStates.delete(id); self.postMessage({ id, type: "result", data: { result } }); } } async function processNormalFile(id, data) { if (!calculator) { await WasmInit(); calculator = new Md5Calculator(); } let fileData; if (data?.dataOffset !== void 0 && data?.dataLength !== void 0 && sharedMemoryView) { fileData = sharedMemoryView.slice( data.dataOffset, data.dataOffset + data.dataLength ); } else if (data?.fileData) { fileData = new Uint8Array(data.fileData); } else { throw new Error("No valid data source provided"); } const result = await calculator.calculate_md5_async( fileData, data.md5Length ); self.postMessage({ id, type: "result", data: { result } }); }