← back to Exo
Fix pdf inputs on Safari (#1865)
2962ebee604ddd701178acc17ca582606a81c9cb · 2026-04-10 15:59:34 +0100 · ciaranbor
## Motivation
PDF attachments weren't working on Safari
## Changes
Create async readable stream if none exists
## Why It Works
pdfjs-dist requires an async readable stream internally
## Test Plan
### Manual Testing
pdf attachments now work on Safari, still work on Firefox
Files touched
M dashboard/src/lib/types/files.ts
Diff
commit 2962ebee604ddd701178acc17ca582606a81c9cb
Author: ciaranbor <81697641+ciaranbor@users.noreply.github.com>
Date: Fri Apr 10 15:59:34 2026 +0100
Fix pdf inputs on Safari (#1865)
## Motivation
PDF attachments weren't working on Safari
## Changes
Create async readable stream if none exists
## Why It Works
pdfjs-dist requires an async readable stream internally
## Test Plan
### Manual Testing
pdf attachments now work on Safari, still work on Firefox
---
dashboard/src/lib/types/files.ts | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/dashboard/src/lib/types/files.ts b/dashboard/src/lib/types/files.ts
index d2231d57..4e2b8641 100644
--- a/dashboard/src/lib/types/files.ts
+++ b/dashboard/src/lib/types/files.ts
@@ -5,6 +5,32 @@
import { getDocument, GlobalWorkerOptions, version } from "pdfjs-dist";
import type { DocumentInitParameters } from "pdfjs-dist/types/src/display/api";
+// Safari (through at least 18/26) does not implement
+// ReadableStream.prototype[Symbol.asyncIterator], which pdfjs-dist uses
+// internally in getTextContent(). Without this polyfill, `for await (const n
+// of stream)` throws "undefined is not a function" and PDF processing fails.
+if (
+ typeof ReadableStream !== "undefined" &&
+ !(ReadableStream.prototype as unknown as Record<symbol, unknown>)[
+ Symbol.asyncIterator
+ ]
+) {
+ (ReadableStream.prototype as unknown as Record<symbol, unknown>)[
+ Symbol.asyncIterator
+ ] = async function* (this: ReadableStream<unknown>) {
+ const reader = this.getReader();
+ try {
+ while (true) {
+ const { done, value } = await reader.read();
+ if (done) return;
+ yield value;
+ }
+ } finally {
+ reader.releaseLock();
+ }
+ };
+}
+
GlobalWorkerOptions.workerSrc = `https://cdn.jsdelivr.net/npm/pdfjs-dist@${version}/build/pdf.worker.mjs`;
const PDF_PAGE_SCALE = 2.0;
← abd75ae0 Truncate long logs with repr (#1854)
·
back to Exo
·
`just package` first builds dashboard (#1867) 93a980a6 →