(_pdfjsUrl: string)
| 93 | >() |
| 94 | |
| 95 | function getWorker(_pdfjsUrl: string): Worker | null { |
| 96 | if (_workerFailed) return null |
| 97 | if (_worker) return _worker |
| 98 | |
| 99 | try { |
| 100 | const blob = new Blob([WORKER_SRC], { type: 'text/javascript' }) |
| 101 | const url = URL.createObjectURL(blob) |
| 102 | _worker = new Worker(url, { type: 'module' }) |
| 103 | |
| 104 | _worker.onmessage = (e: MessageEvent) => { |
| 105 | const { id, blob, error } = e.data |
| 106 | const entry = _pending.get(id) |
| 107 | if (!entry) return |
| 108 | _pending.delete(id) |
| 109 | if (error) { |
| 110 | entry.resolve(null) // Treat worker-side errors as "no result" |
| 111 | } else { |
| 112 | entry.resolve(blob ?? null) |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | _worker.onerror = () => { |
| 117 | // Worker failed to initialize (e.g. module import blocked by CSP) |
| 118 | _workerFailed = true |
| 119 | _worker = null |
| 120 | for (const [, entry] of _pending) { |
| 121 | entry.resolve(null) |
| 122 | } |
| 123 | _pending.clear() |
| 124 | } |
| 125 | |
| 126 | return _worker |
| 127 | } catch { |
| 128 | _workerFailed = true |
| 129 | return null |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | function renderInWorker( |
| 134 | pdfData: Uint8Array, |
no test coverage detected