64 lines
1.7 KiB
TypeScript
64 lines
1.7 KiB
TypeScript
|
|
/// <reference lib="webworker" />
|
||
|
|
import { logger } from '$lib/core/utils/logger';
|
||
|
|
let chunks: Uint8Array[] = [];
|
||
|
|
let totalBytes = 0;
|
||
|
|
let expectedLength = -1;
|
||
|
|
|
||
|
|
self.onmessage = async (e) => {
|
||
|
|
if (e.data.type === 'CHUNK') {
|
||
|
|
const chunk = e.data.payload;
|
||
|
|
chunks.push(chunk);
|
||
|
|
totalBytes += chunk.length;
|
||
|
|
|
||
|
|
// Loop to process complete messages
|
||
|
|
while (true) {
|
||
|
|
// 1. Try to get length header (need 4 bytes)
|
||
|
|
if (expectedLength === -1 && totalBytes >= 4) {
|
||
|
|
// Need a flat buffer just to read the header
|
||
|
|
const headerBuf = concatChunks(chunks, 4);
|
||
|
|
expectedLength = new DataView(headerBuf.buffer).getInt32(0, false);
|
||
|
|
|
||
|
|
// Remove header bytes from our chunks array
|
||
|
|
removeBytes(4);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 2. Try to get payload
|
||
|
|
if (expectedLength !== -1 && totalBytes >= expectedLength) {
|
||
|
|
const payload = concatChunks(chunks, expectedLength);
|
||
|
|
removeBytes(expectedLength);
|
||
|
|
|
||
|
|
self.postMessage({ type: 'DATA', payload }, [payload.buffer]);
|
||
|
|
|
||
|
|
expectedLength = -1; // Reset for next message
|
||
|
|
} else {
|
||
|
|
break; // Wait for more data
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// Helper: Concatenate only what we need
|
||
|
|
function concatChunks(chunks: Uint8Array[], length: number): Uint8Array {
|
||
|
|
const result = new Uint8Array(length);
|
||
|
|
let offset = 0;
|
||
|
|
for (let i = 0; i < chunks.length && offset < length; i++) {
|
||
|
|
const chunk = chunks[i];
|
||
|
|
const toCopy = Math.min(chunk.length, length - offset);
|
||
|
|
result.set(chunk.slice(0, toCopy), offset);
|
||
|
|
// If we only used part of the chunk, we keep the rest in the array
|
||
|
|
if (toCopy < chunk.length) {
|
||
|
|
chunks[i] = chunk.slice(toCopy);
|
||
|
|
} else {
|
||
|
|
chunks.shift();
|
||
|
|
i--;
|
||
|
|
}
|
||
|
|
offset += toCopy;
|
||
|
|
}
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Helper: Update total count
|
||
|
|
function removeBytes(n: number) {
|
||
|
|
totalBytes -= n;
|
||
|
|
}
|