bend_puzzle/field-persistence-worker.js
2026-07-31 12:54:46 +09:00

26 lines
1.7 KiB
JavaScript

'use strict';
importScripts('archive-codec.js');
const{encodeRecord,crc32Update,crc32Hex,parseRecordLine}=self.BendArchiveCodec,MAX_CHUNK_BYTES=1024*1024;
let crc=0xffffffff,rawBytes=0;
function splitBytes(parts){
const chunks=[];let current=new Uint8Array(MAX_CHUNK_BYTES),offset=0;
for(const bytes of parts){let sourceOffset=0;while(sourceOffset<bytes.byteLength){const length=Math.min(current.byteLength-offset,bytes.byteLength-sourceOffset);current.set(bytes.subarray(sourceOffset,sourceOffset+length),offset);offset+=length;sourceOffset+=length;if(offset===current.byteLength){chunks.push(current.buffer);current=new Uint8Array(MAX_CHUNK_BYTES);offset=0}}}
if(offset)chunks.push(current.slice(0,offset).buffer);return chunks;
}
self.onmessage=event=>{
const message=event.data||{},id=message.id;
try{
if(message.op==='encode'){
const parts=[];
for(const record of message.records||[]){const bytes=encodeRecord(record);if(message.includeInCrc!==false){crc=crc32Update(crc,bytes);rawBytes+=bytes.byteLength}parts.push(bytes)}
const chunks=splitBytes(parts);self.postMessage({id,chunks,rawBytes,crc32:crc32Hex(crc)},chunks);return;
}
if(message.op==='parse'){
const items=[];
for(const sourceLine of message.lines||[]){const{record,bytes}=parseRecordLine(sourceLine);if(record?.type!=='end'){crc=crc32Update(crc,bytes);rawBytes+=bytes.byteLength}items.push({record,byteLength:bytes.byteLength,rawBytes,crc32:crc32Hex(crc)})}
self.postMessage({id,items,rawBytes,crc32:crc32Hex(crc)});return;
}
if(message.op==='snapshot'){self.postMessage({id,rawBytes,crc32:crc32Hex(crc)});return}
throw new Error('Unknown archive worker operation.');
}catch(error){self.postMessage({id,error:error?.message||String(error)})}
};