import{uid,timestamp}from'./store.jsx';constsupported=['pdf','docx','txt','md','sql'];functiondeadline(promise,message,milliseconds=10000){returnnewPromise((resolve,reject)=>{consttimer=setTimeout(()=>reject(newError(message)),milliseconds);promise.then(value=>{clearTimeout(timer);resolve(value);},error=>{clearTimeout(timer);reject(error);});});}functionreadFile(file){if (typeofFileReader==='undefined')returnfile.arrayBuffer();returnnewPromise((resolve,reject)=>{constreader=newFileReader();reader.onload=()=>resolve(reader.result);reader.onerror=()=>reject(newError('Could not read this file. Select it again.'));reader.onabort=()=>reject(newError('File reading was interrupted. Select it again.'));reader.readAsArrayBuffer(file);});}functionopenVault(){returnnewPromise((resolve,reject)=>{letsettled=false;constfail=message=>{if (!settled){settled=true;clearTimeout(timer);reject(newError(message));}};consttimer=setTimeout(()=>fail('File storage did not respond. Please try again.'),10000);constrequest=indexedDB.open('ccil-local-files',1);request.onupgradeneeded=()=>{if (!request.result.objectStoreNames.contains('files'))request.result.createObjectStore('files');};request.onsuccess=()=>{if (settled)request.result.close();else{settled=true;clearTimeout(timer);resolve(request.result);}};request.onerror=()=>fail('File storage is unavailable. Please select the file again.');request.onblocked=()=>fail('File storage is busy. Close other studio tabs and try again.');});}asyncfunctionvault(mode,action){constdb=awaitopenVault();try{awaitdeadline(newPromise((resolve,reject)=>{consttransaction=db.transaction('files',mode);action(transaction.objectStore('files'));transaction.oncomplete=resolve;transaction.onerror=()=>reject(newError('Could not save this file. Please try again.'));transaction.onabort=()=>reject(newError('File saving was interrupted. Please try again.'));}),'File saving did not finish. Please try again.');}finally{db.close();}}exportasyncfunctionstageFile(file,scope){constextension=file.name.split('.').pop().toLowerCase();if (!supported.includes(extension))thrownewError(`${file.name}: use PDF, DOCX, TXT, Markdown, or SQL.`);if (file.size>50*1024*1024)thrownewError(`${file.name}: maximum file size is 50 MB.`);if (!file.size)thrownewError(`${file.name}: the file is empty.`);constid=uid('source');constbuffer=awaitdeadline(readFile(file),'File reading did not finish. Please select it again.');constdigest=awaitcrypto.subtle.digest('SHA-256',buffer);constchecksum=Array.from(newUint8Array(digest)).map(b=>b.toString(16).padStart(2,'0')).join('');consttext=['txt','md','sql'].includes(extension)?newTextDecoder().decode(buffer).slice(0,150000):'';if (['txt','md','sql'].includes(extension)&&!text.trim())thrownewError(`${file.name}: no usable text was found.`);awaitvault('readwrite',store=>store.put(file,id));return{id,name:file.name,kind:extension.toUpperCase(),size:`${(file.size/1024).toFixed(1)} KB`,bytes:file.size,checksum,excerpt:text,revision:1,status:'Staged',synthetic:false,date:timestamp(),...scope};}exportasyncfunctionopenOriginal(document){constdb=awaitopenVault();try{constfile=awaitnewPromise((resolve,reject)=>{constrequest=db.transaction('files','readonly').objectStore('files').get(document.id);request.onsuccess=()=>resolve(request.result);request.onerror=reject;});if (!file)thrownewError('The source file is unavailable in this browser. Reattach the original file.');consturl=URL.createObjectURL(file);consta=window.document.createElement('a');a.href=url;a.download=document.name;a.click();setTimeout(()=>URL.revokeObjectURL(url),1000);}finally{db.close();}}
Top comments (0)
Subscribe
We're a place where coders share, stay up-to-date and grow their careers.
Top comments (0)