import {awaitWithAbort} from './abortable.js'; import { readPdfPages } from './pdfDocumentReader.js'; async function openPdf(file,signal) { signal?.throwIfAborted(); const pdfjs = await import('pdfjs-dist'); pdfjs.GlobalWorkerOptions.workerSrc = (await import('pdfjs-dist/build/pdf.worker.min.mjs?url')).default; let task,destruction; const destroy=()=>destruction ||= task?.destroy(); try { const data=await awaitWithAbort(file.arrayBuffer(),signal); signal?.throwIfAborted(); task = pdfjs.getDocument({data}); return {doc:await awaitWithAbort(task.promise,signal,destroy),task:{destroy}}; } catch(error) { await destroy(); signal?.throwIfAborted(); if(error.name === 'InvalidPDFException') throw new Error('PDF dosyası bozuk veya geçerli PDF biçiminde değil.'); if(error.name === 'PasswordException') throw new Error('PDF parola korumalı; okunabilir bir kopyasını yükleyin.'); throw new Error('PDF okunamadı. Dosyayı kontrol edip yeniden deneyin.'); } } async function readPdf(file,{ocr=false,forceOcr=false,maxPages=Infinity,onProgress,signal}={}) { const {doc,task}=await openPdf(file,signal); let worker,termination,render; const stopWorker=()=>termination ||= worker?.terminate(); const cancel=()=>{render?.cancel();void Promise.resolve(stopWorker()).catch(()=>{});void Promise.resolve(task.destroy()).catch(()=>{});}; signal?.addEventListener('abort',cancel,{once:true}); try { signal?.throwIfAborted(); const result=await readPdfPages(doc,{maxPages,forceOcr,onProgress,signal,ocrPage:ocr ? async(page)=>{ if(!worker) { const {createWorker}=await import('tesseract.js'); signal?.throwIfAborted(); worker=await awaitWithAbort(createWorker('tur').then(created=>{ if(signal?.aborted){void created.terminate().catch(()=>{});signal.throwIfAborted();} return created; }),signal); } const viewport=page.getViewport({scale:2}); const canvas=document.createElement('canvas'); canvas.width=viewport.width;canvas.height=viewport.height; try { signal?.throwIfAborted(); render=page.render({canvasContext:canvas.getContext('2d'),viewport}); await awaitWithAbort(render.promise,signal,()=>render.cancel()); signal?.throwIfAborted(); return (await awaitWithAbort(worker.recognize(canvas),signal,stopWorker)).data.text; } finally { render=null;canvas.width=0;canvas.height=0; } } : undefined}); return result; } finally { signal?.removeEventListener('abort',cancel); try { await stopWorker(); } finally { await task.destroy(); } } } export const extractPdfText=(file,options={})=>readPdf(file,{...options,ocr:false}); export const ocrPdfText=(file,options={})=>readPdf(file,{...options,ocr:true,forceOcr:true}); export async function extractPlainText(file,{signal}={}) { signal?.throwIfAborted(); return {text:(await awaitWithAbort(file.text(),signal)).trim(),pageCount:1,usedPages:1,complete:true}; } export async function extractText(file,{ocr=true,onProgress,signal}={}) { if((file.name || '').toLowerCase().endsWith('.pdf') || file.type==='application/pdf') return readPdf(file,{ocr,onProgress,signal}); return extractPlainText(file,{signal}); }