Skip to content

Commit

Permalink
Realtime fixes: safari, timezones, and TIMED_OUT status (#1585)
Browse files Browse the repository at this point in the history
* Fix realtime safari bug because of missing ReadableStream async iterable support
Limit to only safari

* Fix missing TIMED_OUT run status

* When coercing realtime date strings, make sure they are set to UTC
  • Loading branch information
ericallam authored Jan 7, 2025
1 parent 668b34d commit 76a5ac2
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/poor-shirts-move.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@trigger.dev/core": patch
---

Fix realtime safari bug because of missing ReadableStream async iterable support
5 changes: 5 additions & 0 deletions .changeset/silent-trees-jump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@trigger.dev/core": patch
---

Fix issue with dates in realtime not reflecting the current timezone
69 changes: 69 additions & 0 deletions packages/core/src/v3/apiClient/runStream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,9 @@ function apiStatusFromRunStatus(status: string): RunStatus {
case "EXPIRED": {
return "EXPIRED";
}
case "TIMED_OUT": {
return "TIMED_OUT";
}
default: {
throw new Error(`Unknown status: ${status}`);
}
Expand All @@ -541,3 +544,69 @@ function safeParseJSON(data: string): unknown {
return data;
}
}

const isSafari = () => {
// Check if we're in a browser environment
if (
typeof window !== "undefined" &&
typeof navigator !== "undefined" &&
typeof navigator.userAgent === "string"
) {
return (
/^((?!chrome|android).)*safari/i.test(navigator.userAgent) ||
/iPad|iPhone|iPod/.test(navigator.userAgent)
);
}
// If we're not in a browser environment, return false
return false;
};

/**
* A polyfill for `ReadableStream.protototype[Symbol.asyncIterator]`,
* aligning as closely as possible to the specification.
*
* @see https://streams.spec.whatwg.org/#rs-asynciterator
* @see https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream#async_iteration
*
* This is needed for Safari: https://bugs.webkit.org/show_bug.cgi?id=194379
*
* From https://gist.github.com/MattiasBuelens/496fc1d37adb50a733edd43853f2f60e
*
*/

if (isSafari()) {
// @ts-expect-error
ReadableStream.prototype.values ??= function ({ preventCancel = false } = {}) {
const reader = this.getReader();
return {
async next() {
try {
const result = await reader.read();
if (result.done) {
reader.releaseLock();
}
return result;
} catch (e) {
reader.releaseLock();
throw e;
}
},
async return(value: unknown) {
if (!preventCancel) {
const cancelPromise = reader.cancel(value);
reader.releaseLock();
await cancelPromise;
} else {
reader.releaseLock();
}
return { done: true, value };
},
[Symbol.asyncIterator]() {
return this;
},
};
};

// @ts-expect-error
ReadableStream.prototype[Symbol.asyncIterator] ??= ReadableStream.prototype.values;
}
24 changes: 17 additions & 7 deletions packages/core/src/v3/schemas/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -682,16 +682,26 @@ export const UpdateMetadataResponseBody = z.object({

export type UpdateMetadataResponseBody = z.infer<typeof UpdateMetadataResponseBody>;

const RawShapeDate = z
.string()
.transform((val) => `${val}Z`)
.pipe(z.coerce.date());

const RawOptionalShapeDate = z
.string()
.nullish()
.transform((val) => (val ? new Date(`${val}Z`) : val));

export const SubscribeRunRawShape = z.object({
id: z.string(),
idempotencyKey: z.string().nullish(),
createdAt: z.coerce.date(),
updatedAt: z.coerce.date(),
startedAt: z.coerce.date().nullish(),
delayUntil: z.coerce.date().nullish(),
queuedAt: z.coerce.date().nullish(),
expiredAt: z.coerce.date().nullish(),
completedAt: z.coerce.date().nullish(),
createdAt: RawShapeDate,
updatedAt: RawShapeDate,
startedAt: RawOptionalShapeDate,
delayUntil: RawOptionalShapeDate,
queuedAt: RawOptionalShapeDate,
expiredAt: RawOptionalShapeDate,
completedAt: RawOptionalShapeDate,
taskIdentifier: z.string(),
friendlyId: z.string(),
number: z.number(),
Expand Down

0 comments on commit 76a5ac2

Please sign in to comment.