Files
RaptorQR/src/workers/encode.worker.ts
T
Hermes Agent 8d894b08e6 feat(receiver): remove sessions, add filename/mime, fix gen counter, compact UI
- Removed session tracking entirely; single global decode state
- Receiver UI: no sessions table, no big progress bar
- Inline stats above video: scanned / useful / need  ·  gen X of Y
- Sender passes filename and mimeType to encode worker
- Packetizer wraps file payloads with [filenameLen][name][mimeLen][mime] header
- Decode worker parses metadata and uses it for download name/type
- Fixed generation counter bug: final progress was skipped when reconstruction
  succeeded; now reportProgress is called right before early return
2026-05-03 13:31:47 +00:00

72 lines
2.2 KiB
TypeScript

/**
* Encode worker — receives raw data, compresses, packetizes, schedules.
*
* @module
*/
import { packetize } from '@/core/sender/packetizer';
import { scheduleFrames } from '@/core/sender/scheduler';
// ─── Types ───────────────────────────────────────────────────────────────────
interface EncodeInput {
type: 'encode';
data: ArrayBuffer;
isText: boolean;
compress: boolean;
filename?: string;
mimeType?: string;
}
interface EncodeOutput {
type: 'encoded';
packets: Uint8Array[];
sessionId: number;
totalGenerations: number;
stats: {
originalSize: number;
preprocessedSize: number;
frameCount: number;
};
}
interface ErrorOutput {
type: 'error';
message: string;
}
// ─── Worker handler ───────────────────────────────────────────────────────────────────
self.onmessage = (e: MessageEvent<EncodeInput>) => {
const msg = e.data;
if (msg.type !== 'encode') return;
try {
const result = handleEncode(msg);
const transfer: ArrayBufferLike[] = result.packets
.map((p) => p.buffer as ArrayBuffer)
.filter((b): b is ArrayBuffer => b instanceof ArrayBuffer && b.byteLength <= 1024 * 1024);
self.postMessage(result, transfer.length > 0 ? { transfer } : undefined);
} catch (err: any) {
self.postMessage({ type: 'error', message: err.message ?? String(err) } satisfies ErrorOutput);
}
};
function handleEncode(input: EncodeInput): EncodeOutput {
const originalBytes = new Uint8Array(input.data);
const result = packetize(originalBytes, input.isText, input.compress, input.filename, input.mimeType);
const frames = scheduleFrames(result.packets, result.totalGenerations, result.sessionId);
return {
type: 'encoded',
packets: frames,
sessionId: result.sessionId,
totalGenerations: result.totalGenerations,
stats: {
originalSize: originalBytes.length,
preprocessedSize: result.dataLength,
frameCount: frames.length,
},
};
}