export type BatchItemStatus = 'pending' | 'processing' | 'done' | 'error'; export type BatchItem = { id: string; file: File; status: BatchItemStatus; resultBytes?: Uint8Array; resultName?: string; errorMessage?: string | null; }; export type BatchProcessResult = { bytes: Uint8Array; name: string }; export type BatchRunOptions = { /** * Error message written to a row when `process` throws for it. A function * receives the thrown error so tools can surface a specific German message. */ errorMessage?: string | ((error: unknown, file: File) => string); /** * Optional predicate consulted before each item; when it returns `false` * (for example because the row was removed mid-run), the item is skipped. */ shouldProcess?: (id: string) => boolean; }; export const createBatchItem = (file: File): BatchItem => ({ id: crypto.randomUUID(), file, status: 'pending' }); /** * Processes the given items strictly one after another so only one PDF is in * flight at a time. Never throws: a failing item is marked as an error row and * the queue continues with the remaining files. */ export const runBatch = async ( items: BatchItem[], process: (file: File) => Promise, update: (id: string, patch: Partial) => void, options: BatchRunOptions = {} ): Promise => { const { errorMessage = 'Die Datei konnte nicht verarbeitet werden.', shouldProcess } = options; for (const item of items) { if (shouldProcess && !shouldProcess(item.id)) continue; update(item.id, { status: 'processing', errorMessage: null }); try { const result = await process(item.file); update(item.id, { status: 'done', resultBytes: result.bytes, resultName: result.name, errorMessage: null }); } catch (error) { console.error(`Batch processing failed for ${item.file.name}:`, error); update(item.id, { status: 'error', resultBytes: undefined, resultName: undefined, errorMessage: typeof errorMessage === 'function' ? errorMessage(error, item.file) : errorMessage }); } } }; export const formatBytes = (bytes: number) => { if (bytes < 1024) return `${bytes} B`; if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`; return `${(bytes / (1024 * 1024)).toFixed(1)} MB`; };