Skip to content

Commit 8d78972

Browse files
committed
Fix realtime safari bug because of missing ReadableStream async iterable support
Limit to only safari
1 parent 668b34d commit 8d78972

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

.changeset/poor-shirts-move.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@trigger.dev/core": patch
3+
---
4+
5+
Fix realtime safari bug because of missing ReadableStream async iterable support

packages/core/src/v3/apiClient/runStream.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,3 +541,69 @@ function safeParseJSON(data: string): unknown {
541541
return data;
542542
}
543543
}
544+
545+
const isSafari = () => {
546+
// Check if we're in a browser environment
547+
if (
548+
typeof window !== "undefined" &&
549+
typeof navigator !== "undefined" &&
550+
typeof navigator.userAgent === "string"
551+
) {
552+
return (
553+
/^((?!chrome|android).)*safari/i.test(navigator.userAgent) ||
554+
/iPad|iPhone|iPod/.test(navigator.userAgent)
555+
);
556+
}
557+
// If we're not in a browser environment, return false
558+
return false;
559+
};
560+
561+
/**
562+
* A polyfill for `ReadableStream.protototype[Symbol.asyncIterator]`,
563+
* aligning as closely as possible to the specification.
564+
*
565+
* @see https://streams.spec.whatwg.org/#rs-asynciterator
566+
* @see https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream#async_iteration
567+
*
568+
* This is needed for Safari: https://bugs.webkit.org/show_bug.cgi?id=194379
569+
*
570+
* From https://gist.github.com/MattiasBuelens/496fc1d37adb50a733edd43853f2f60e
571+
*
572+
*/
573+
574+
if (isSafari()) {
575+
// @ts-expect-error
576+
ReadableStream.prototype.values ??= function ({ preventCancel = false } = {}) {
577+
const reader = this.getReader();
578+
return {
579+
async next() {
580+
try {
581+
const result = await reader.read();
582+
if (result.done) {
583+
reader.releaseLock();
584+
}
585+
return result;
586+
} catch (e) {
587+
reader.releaseLock();
588+
throw e;
589+
}
590+
},
591+
async return(value: unknown) {
592+
if (!preventCancel) {
593+
const cancelPromise = reader.cancel(value);
594+
reader.releaseLock();
595+
await cancelPromise;
596+
} else {
597+
reader.releaseLock();
598+
}
599+
return { done: true, value };
600+
},
601+
[Symbol.asyncIterator]() {
602+
return this;
603+
},
604+
};
605+
};
606+
607+
// @ts-expect-error
608+
ReadableStream.prototype[Symbol.asyncIterator] ??= ReadableStream.prototype.values;
609+
}

0 commit comments

Comments
 (0)