15 lines
1.6 KiB
TypeScript
15 lines
1.6 KiB
TypeScript
import {fault} from '../canvas-core/values.ts';
|
|
import {createDigestPool} from './digest-pool.ts';
|
|
/** Browser capability stays at the adapter; WorkspaceRuntime owns the pool's lifetime. */
|
|
export function createBrowserDigests(){
|
|
let next=0;
|
|
return createDigestPool({execute:typeof Worker==='undefined'?undefined:(bytes,signal)=>new Promise<string>((resolve,reject)=>{
|
|
if(signal.aborted){reject(fault('import_aborted'));return;}
|
|
let worker:Worker;try{worker=new Worker(new URL('./digest.worker.ts',import.meta.url),{type:'module'});}catch{reject(fault('digest_worker_unavailable'));return;}
|
|
const id=++next;let done=false;
|
|
const finish=(error?:unknown,sha256?:string)=>{if(done)return;done=true;signal.removeEventListener('abort',abort);worker.onmessage=null;worker.onerror=null;worker.onmessageerror=null;worker.terminate();if(error)reject(error);else resolve(sha256!);},abort=()=>finish(fault('import_aborted'));
|
|
signal.addEventListener('abort',abort,{once:true});worker.onmessage=event=>{const value=event.data;if(value?.version===1&&value.id===id&&value.byteLength===bytes.size&&value.error==='digest_worker_failed'){finish(fault('digest_worker_failed'));return;}if(!value||value.version!==1||value.id!==id||value.byteLength!==bytes.size||typeof value.sha256!=='string'||!(/^[a-f0-9]{64}$/.test(value.sha256)))finish(fault('invalid_digest_response'));else finish(undefined,value.sha256);};worker.onerror=event=>{event.preventDefault();finish(fault('digest_worker_failed'));};worker.onmessageerror=()=>finish(fault('invalid_digest_response'));
|
|
try{worker.postMessage({version:1,id,bytes});}catch{finish(fault('digest_worker_failed'));}
|
|
})});
|
|
}
|