Cancel PDF reading and OCR when the offer assistant closes

This commit is contained in:
2026-09-06 10:24:07 +03:00
parent d534ea20b9
commit 3ad9348c20
6 changed files with 109 additions and 25 deletions
+38 -19
View File
@@ -1,52 +1,71 @@
import {awaitWithAbort} from './abortable.js';
import { readPdfPages } from './pdfDocumentReader.js';
async function openPdf(file) {
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;
let task,destruction;
const destroy=()=>destruction ||= task?.destroy();
try {
task = pdfjs.getDocument({data:await file.arrayBuffer()});
return {doc:await task.promise,task};
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 task?.destroy();
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}={}) {
const {doc,task}=await openPdf(file);
let worker;
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 {
const result=await readPdfPages(doc,{maxPages,forceOcr,onProgress,ocrPage:ocr ? async(page)=>{
signal?.throwIfAborted();
const result=await readPdfPages(doc,{maxPages,forceOcr,onProgress,signal,ocrPage:ocr ? async(page)=>{
if(!worker) {
const {createWorker}=await import('tesseract.js');
worker=await createWorker('tur');
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 {
await page.render({canvasContext:canvas.getContext('2d'),viewport}).promise;
return (await worker.recognize(canvas)).data.text;
} finally { canvas.width=0;canvas.height=0; }
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 {
try { if(worker) await worker.terminate(); }
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) {
return {text:(await file.text()).trim(),pageCount:1,usedPages:1,complete: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}={}) {
export async function extractText(file,{ocr=true,onProgress,signal}={}) {
if((file.name || '').toLowerCase().endsWith('.pdf') || file.type==='application/pdf')
return readPdf(file,{ocr,onProgress});
return extractPlainText(file);
return readPdf(file,{ocr,onProgress,signal});
return extractPlainText(file,{signal});
}