2026-01-27 15:26:11 +05:30
let cpdfLoaded = false ;
function loadCpdf ( cpdfUrl ) {
if ( cpdfLoaded ) return Promise . resolve ( ) ;
return new Promise ( ( resolve , reject ) => {
if ( typeof coherentpdf !== 'undefined' ) {
cpdfLoaded = true ;
resolve ( ) ;
return ;
}
try {
self . importScripts ( cpdfUrl ) ;
cpdfLoaded = true ;
resolve ( ) ;
} catch ( error ) {
reject ( new Error ( 'Failed to load CoherentPDF: ' + error . message ) ) ;
}
} ) ;
}
2025-11-18 20:31:13 +05:30
2025-11-19 13:19:14 +05:30
function parsePageRange ( rangeString , totalPages ) {
const pages = new Set ( ) ;
2026-01-27 15:26:11 +05:30
const parts = rangeString . split ( ',' ) . map ( ( s ) => s . trim ( ) ) ;
2025-11-19 13:19:14 +05:30
for ( const part of parts ) {
if ( part . includes ( '-' ) ) {
2026-01-27 15:26:11 +05:30
const [ start , end ] = part . split ( '-' ) . map ( ( s ) => parseInt ( s . trim ( ) , 10 ) ) ;
2025-11-19 13:19:14 +05:30
if ( isNaN ( start ) || isNaN ( end ) ) continue ;
for ( let i = Math . max ( 1 , start ) ; i <= Math . min ( totalPages , end ) ; i ++ ) {
pages . add ( i ) ;
}
} else {
const pageNum = parseInt ( part , 10 ) ;
if ( ! isNaN ( pageNum ) && pageNum >= 1 && pageNum <= totalPages ) {
pages . add ( pageNum ) ;
}
}
}
return Array . from ( pages ) . sort ( ( a , b ) => a - b ) ;
}
2026-01-27 15:26:11 +05:30
function addAttachmentsToPDFInWorker (
pdfBuffer ,
attachmentBuffers ,
attachmentNames ,
attachmentLevel ,
pageRange
) {
2025-11-18 20:31:13 +05:30
try {
const uint8Array = new Uint8Array ( pdfBuffer ) ;
2025-11-19 13:19:14 +05:30
2025-11-18 20:31:13 +05:30
let pdf ;
try {
pdf = coherentpdf . fromMemory ( uint8Array , '' ) ;
} catch ( error ) {
2025-11-19 13:19:14 +05:30
const errorMsg = error . message || error . toString ( ) ;
2026-01-27 15:26:11 +05:30
if (
errorMsg . includes ( 'Failed to read PDF' ) ||
2025-11-19 13:19:14 +05:30
errorMsg . includes ( 'Could not read object' ) ||
errorMsg . includes ( 'No /Root entry' ) ||
2026-01-27 15:26:11 +05:30
errorMsg . includes ( 'PDFError' )
) {
2025-11-19 13:19:14 +05:30
self . postMessage ( {
status : 'error' ,
2026-01-27 15:26:11 +05:30
message :
'The PDF file has structural issues and cannot be processed. The file may be corrupted, incomplete, or created with non-standard tools. Please try:\n\n• Opening and re-saving the PDF in another PDF viewer\n• Using a different PDF file\n• Repairing the PDF with a PDF repair tool' ,
2025-11-19 13:19:14 +05:30
} ) ;
} else {
self . postMessage ( {
status : 'error' ,
2026-01-27 15:26:11 +05:30
message : ` Failed to load PDF: ${ errorMsg } ` ,
2025-11-19 13:19:14 +05:30
} ) ;
}
2025-11-18 20:31:13 +05:30
return ;
}
2025-11-19 13:19:14 +05:30
const totalPages = coherentpdf . pages ( pdf ) ;
let targetPages = [ ] ;
if ( attachmentLevel === 'page' ) {
if ( ! pageRange ) {
self . postMessage ( {
status : 'error' ,
2026-01-27 15:26:11 +05:30
message : 'Page range is required for page-level attachments.' ,
2025-11-19 13:19:14 +05:30
} ) ;
coherentpdf . deletePdf ( pdf ) ;
return ;
}
targetPages = parsePageRange ( pageRange , totalPages ) ;
if ( targetPages . length === 0 ) {
self . postMessage ( {
status : 'error' ,
2026-01-27 15:26:11 +05:30
message : 'Invalid page range specified.' ,
2025-11-19 13:19:14 +05:30
} ) ;
coherentpdf . deletePdf ( pdf ) ;
return ;
}
}
2025-11-18 20:31:13 +05:30
for ( let i = 0 ; i < attachmentBuffers . length ; i ++ ) {
try {
const attachmentData = new Uint8Array ( attachmentBuffers [ i ] ) ;
const attachmentName = attachmentNames [ i ] ;
2025-11-19 13:19:14 +05:30
if ( attachmentLevel === 'document' ) {
coherentpdf . attachFileFromMemory ( attachmentData , attachmentName , pdf ) ;
} else {
for ( const pageNum of targetPages ) {
2026-01-27 15:26:11 +05:30
coherentpdf . attachFileToPageFromMemory (
attachmentData ,
attachmentName ,
pdf ,
pageNum
) ;
2025-11-19 13:19:14 +05:30
}
}
2025-11-18 20:31:13 +05:30
} catch ( error ) {
console . warn ( ` Failed to attach file ${ attachmentNames [ i ] } : ` , error ) ;
self . postMessage ( {
status : 'error' ,
2026-01-27 15:26:11 +05:30
message : ` Failed to attach file ${ attachmentNames [ i ] } : ${ error . message || error } ` ,
2025-11-18 20:31:13 +05:30
} ) ;
coherentpdf . deletePdf ( pdf ) ;
return ;
}
}
2025-11-19 13:19:14 +05:30
2025-11-18 20:31:13 +05:30
const modifiedBytes = coherentpdf . toMemory ( pdf , false , false ) ;
coherentpdf . deletePdf ( pdf ) ;
const buffer = modifiedBytes . buffer . slice (
2025-11-19 13:19:14 +05:30
modifiedBytes . byteOffset ,
2025-11-18 20:31:13 +05:30
modifiedBytes . byteOffset + modifiedBytes . byteLength
) ;
2026-01-27 15:26:11 +05:30
self . postMessage (
{
status : 'success' ,
modifiedPDF : buffer ,
} ,
[ buffer ]
) ;
} catch ( error ) {
2025-11-18 20:31:13 +05:30
self . postMessage ( {
2026-01-27 15:26:11 +05:30
status : 'error' ,
message :
error instanceof Error
? error . message
: 'Unknown error occurred while adding attachments.' ,
} ) ;
}
}
2025-11-19 13:19:14 +05:30
2026-01-27 15:26:11 +05:30
self . onmessage = async function ( e ) {
const { cpdfUrl } = e . data ;
if ( ! cpdfUrl ) {
self . postMessage ( {
status : 'error' ,
message :
'CoherentPDF URL not provided. Please configure it in WASM Settings.' ,
} ) ;
return ;
}
try {
await loadCpdf ( cpdfUrl ) ;
2025-11-18 20:31:13 +05:30
} catch ( error ) {
self . postMessage ( {
status : 'error' ,
2026-01-27 15:26:11 +05:30
message : error . message ,
2025-11-18 20:31:13 +05:30
} ) ;
2026-01-27 15:26:11 +05:30
return ;
2025-11-18 20:31:13 +05:30
}
if ( e . data . command === 'add-attachments' ) {
addAttachmentsToPDFInWorker (
2025-11-19 13:19:14 +05:30
e . data . pdfBuffer ,
e . data . attachmentBuffers ,
e . data . attachmentNames ,
e . data . attachmentLevel || 'document' ,
e . data . pageRange || ''
2025-11-18 20:31:13 +05:30
) ;
}
} ;