Skip to content

Commit 0efc415

Browse files
committed
Added wait.listTokens() function. Made some changes to the types to make it nicer
1 parent 461e987 commit 0efc415

File tree

16 files changed

+394
-66
lines changed

16 files changed

+394
-66
lines changed

apps/webapp/app/components/runs/v3/WaitpointDetails.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ export function WaitpointDetailTable({
8484
) : (
8585
"–"
8686
)}
87-
{waitpoint.status === "PENDING" && <ForceTimeout waitpoint={waitpoint} />}
87+
{waitpoint.status === "WAITING" && <ForceTimeout waitpoint={waitpoint} />}
8888
</div>
8989
<Paragraph variant="extra-small" className="text-text-dimmed/70">
9090
{waitpoint.isTimeout
@@ -112,7 +112,7 @@ export function WaitpointDetailTable({
112112
</Property.Item>
113113
</>
114114
)}
115-
{waitpoint.status === "PENDING" ? null : waitpoint.isTimeout ? (
115+
{waitpoint.status === "WAITING" ? null : waitpoint.isTimeout ? (
116116
<></>
117117
) : waitpoint.output ? (
118118
<PacketDisplay title="Output" data={waitpoint.output} dataType={waitpoint.outputType} />

apps/webapp/app/components/runs/v3/WaitpointStatus.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ export function WaitpointStatusIcon({
3636
className: string;
3737
}) {
3838
switch (status) {
39-
case "PENDING":
39+
case "WAITING":
4040
return <Spinner className={cn(waitpointStatusClassNameColor(status), className)} />;
41-
case "FAILED":
41+
case "TIMED_OUT":
4242
return <TimedOutIcon className={cn(waitpointStatusClassNameColor(status), className)} />;
4343
case "COMPLETED":
4444
return <CheckCircleIcon className={cn(waitpointStatusClassNameColor(status), className)} />;
@@ -50,9 +50,9 @@ export function WaitpointStatusIcon({
5050

5151
export function waitpointStatusClassNameColor(status: WaitpointTokenStatus): string {
5252
switch (status) {
53-
case "PENDING":
53+
case "WAITING":
5454
return "text-blue-500";
55-
case "FAILED":
55+
case "TIMED_OUT":
5656
return "text-error";
5757
case "COMPLETED": {
5858
return "text-success";
@@ -65,9 +65,9 @@ export function waitpointStatusClassNameColor(status: WaitpointTokenStatus): str
6565

6666
export function waitpointStatusTitle(status: WaitpointTokenStatus): string {
6767
switch (status) {
68-
case "PENDING":
68+
case "WAITING":
6969
return "Waiting";
70-
case "FAILED":
70+
case "TIMED_OUT":
7171
return "Timed out";
7272
case "COMPLETED": {
7373
return "Completed";

apps/webapp/app/components/runs/v3/WaitpointTokenFilters.tsx

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ import {
4444
CustomDateRangeDropdown,
4545
FilterMenuProvider,
4646
} from "./SharedFilters";
47-
import { WaitpointStatusCombo } from "./WaitpointStatus";
47+
import { WaitpointStatusCombo, waitpointStatusTitle } from "./WaitpointStatus";
4848

4949
export const WaitpointSearchParamsSchema = z.object({
5050
id: z.string().optional(),
@@ -217,24 +217,10 @@ function MainMenu({ searchValue, trigger, clearSearchValue, setFilterType }: Men
217217
}
218218

219219
const statuses = waitpointTokenStatuses.map((status) => ({
220-
title: statusTitle(status),
220+
title: waitpointStatusTitle(status),
221221
value: status,
222222
}));
223223

224-
function statusTitle(status: WaitpointTokenStatus) {
225-
switch (status) {
226-
case "COMPLETED": {
227-
return "Completed";
228-
}
229-
case "FAILED": {
230-
return "Timed out";
231-
}
232-
case "PENDING": {
233-
return "Waiting";
234-
}
235-
}
236-
}
237-
238224
function StatusDropdown({
239225
trigger,
240226
clearSearchValue,
@@ -286,7 +272,9 @@ function StatusDropdown({
286272
<WaitpointStatusCombo status={item.value} />
287273
</TooltipTrigger>
288274
<TooltipContent side="right" sideOffset={50}>
289-
<Paragraph variant="extra-small">{statusTitle(item.value)}</Paragraph>
275+
<Paragraph variant="extra-small">
276+
{waitpointStatusTitle(item.value)}
277+
</Paragraph>
290278
</TooltipContent>
291279
</Tooltip>
292280
</TooltipProvider>
@@ -315,7 +303,9 @@ function AppliedStatusFilter() {
315303
<Ariakit.Select render={<div className="group cursor-pointer focus-custom" />}>
316304
<AppliedFilter
317305
label="Status"
318-
value={appliedSummary(statuses.map((v) => statusTitle(v as WaitpointTokenStatus)))}
306+
value={appliedSummary(
307+
statuses.map((v) => waitpointStatusTitle(v as WaitpointTokenStatus))
308+
)}
319309
onRemove={() => del(["statuses", "cursor", "direction"])}
320310
/>
321311
</Ariakit.Select>

apps/webapp/app/presenters/v3/ApiRunListPresenter.server.ts

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,18 @@
1-
import { ListRunResponse, ListRunResponseItem, parsePacket, RunStatus } from "@trigger.dev/core/v3";
2-
import { Project, RuntimeEnvironment, TaskRunStatus } from "@trigger.dev/database";
1+
import {
2+
type ListRunResponse,
3+
type ListRunResponseItem,
4+
parsePacket,
5+
RunStatus,
6+
} from "@trigger.dev/core/v3";
7+
import { type Project, type RuntimeEnvironment, type TaskRunStatus } from "@trigger.dev/database";
38
import assertNever from "assert-never";
49
import { z } from "zod";
5-
import { fromZodError } from "zod-validation-error";
610
import { logger } from "~/services/logger.server";
11+
import { CoercedDate } from "~/utils/zod";
712
import { ApiRetrieveRunPresenter } from "./ApiRetrieveRunPresenter.server";
8-
import { RunListOptions, RunListPresenter } from "./RunListPresenter.server";
13+
import { type RunListOptions, RunListPresenter } from "./RunListPresenter.server";
914
import { BasePresenter } from "./basePresenter.server";
1015

11-
const CoercedDate = z.preprocess((arg) => {
12-
if (arg === undefined || arg === null) {
13-
return;
14-
}
15-
16-
if (typeof arg === "number") {
17-
return new Date(arg);
18-
}
19-
20-
if (typeof arg === "string") {
21-
const num = Number(arg);
22-
if (!isNaN(num)) {
23-
return new Date(num);
24-
}
25-
26-
return new Date(arg);
27-
}
28-
29-
return arg;
30-
}, z.date().optional());
31-
3216
export const ApiRunListSearchParams = z.object({
3317
"page[size]": z.coerce.number().int().positive().min(1).max(100).optional(),
3418
"page[after]": z.string().optional(),
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import { RuntimeEnvironmentType, WaitpointTokenStatus } from "@trigger.dev/core/v3";
2+
import { z } from "zod";
3+
import { BasePresenter } from "./basePresenter.server";
4+
import { CoercedDate } from "~/utils/zod";
5+
import { AuthenticatedEnvironment } from "@internal/run-engine";
6+
import {
7+
WaitpointTokenListOptions,
8+
WaitpointTokenListPresenter,
9+
} from "./WaitpointTokenListPresenter.server";
10+
import { ServiceValidationError } from "~/v3/services/baseService.server";
11+
import { RunEngineVersion } from "@trigger.dev/database";
12+
13+
export const ApiWaitpointTokenListSearchParams = z.object({
14+
"page[size]": z.coerce.number().int().positive().min(1).max(100).optional(),
15+
"page[after]": z.string().optional(),
16+
"page[before]": z.string().optional(),
17+
"filter[status]": z
18+
.string()
19+
.optional()
20+
.transform((value, ctx) => {
21+
if (!value) {
22+
return undefined;
23+
}
24+
25+
const statuses = value.split(",");
26+
const parsedStatuses = statuses.map((status) => WaitpointTokenStatus.safeParse(status));
27+
28+
if (parsedStatuses.some((result) => !result.success)) {
29+
const invalidStatuses: string[] = [];
30+
31+
for (const [index, result] of parsedStatuses.entries()) {
32+
if (!result.success) {
33+
invalidStatuses.push(statuses[index]);
34+
}
35+
}
36+
37+
ctx.addIssue({
38+
code: z.ZodIssueCode.custom,
39+
message: `Invalid status values: ${invalidStatuses.join(", ")}`,
40+
});
41+
42+
return z.NEVER;
43+
}
44+
45+
const $statuses = parsedStatuses
46+
.map((result) => (result.success ? result.data : undefined))
47+
.filter(Boolean);
48+
49+
return Array.from(new Set($statuses));
50+
}),
51+
"filter[idempotencyKey]": z.string().optional(),
52+
"filter[tags]": z
53+
.string()
54+
.optional()
55+
.transform((value) => {
56+
if (!value) return undefined;
57+
return value.split(",");
58+
}),
59+
"filter[createdAt][period]": z.string().optional(),
60+
"filter[createdAt][from]": CoercedDate,
61+
"filter[createdAt][to]": CoercedDate,
62+
});
63+
64+
type ApiWaitpointTokenListSearchParams = z.infer<typeof ApiWaitpointTokenListSearchParams>;
65+
66+
export class ApiWaitpointTokenListPresenter extends BasePresenter {
67+
public async call(
68+
environment: {
69+
id: string;
70+
type: RuntimeEnvironmentType;
71+
project: {
72+
id: string;
73+
engine: RunEngineVersion;
74+
};
75+
},
76+
searchParams: ApiWaitpointTokenListSearchParams
77+
) {
78+
return this.trace("call", async (span) => {
79+
const options: WaitpointTokenListOptions = {
80+
environment,
81+
};
82+
83+
if (searchParams["page[size]"]) {
84+
options.pageSize = searchParams["page[size]"];
85+
}
86+
87+
if (searchParams["page[after]"]) {
88+
options.cursor = searchParams["page[after]"];
89+
options.direction = "forward";
90+
}
91+
92+
if (searchParams["page[before]"]) {
93+
options.cursor = searchParams["page[before]"];
94+
options.direction = "backward";
95+
}
96+
97+
if (searchParams["filter[status]"]) {
98+
options.statuses = searchParams["filter[status]"];
99+
}
100+
101+
if (searchParams["filter[idempotencyKey]"]) {
102+
options.idempotencyKey = searchParams["filter[idempotencyKey]"];
103+
}
104+
105+
if (searchParams["filter[tags]"]) {
106+
options.tags = searchParams["filter[tags]"];
107+
}
108+
109+
if (searchParams["filter[createdAt][period]"]) {
110+
options.period = searchParams["filter[createdAt][period]"];
111+
}
112+
113+
if (searchParams["filter[createdAt][from]"]) {
114+
options.from = searchParams["filter[createdAt][from]"].getTime();
115+
}
116+
117+
if (searchParams["filter[createdAt][to]"]) {
118+
options.to = searchParams["filter[createdAt][to]"].getTime();
119+
}
120+
121+
const presenter = new WaitpointTokenListPresenter();
122+
const result = await presenter.call(options);
123+
124+
if (!result.success) {
125+
throw new ServiceValidationError(result.error);
126+
}
127+
128+
return {
129+
data: result.tokens,
130+
pagination: result.pagination,
131+
};
132+
});
133+
}
134+
}

apps/webapp/app/presenters/v3/WaitpointPresenter.server.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { isWaitpointOutputTimeout, prettyPrintPacket } from "@trigger.dev/core/v
22
import { logger } from "~/services/logger.server";
33
import { BasePresenter } from "./basePresenter.server";
44
import { type RunListItem, RunListPresenter } from "./RunListPresenter.server";
5+
import { waitpointStatusToApiStatus } from "./WaitpointTokenListPresenter.server";
56

67
export type WaitpointDetail = NonNullable<Awaited<ReturnType<WaitpointPresenter["call"]>>>;
78

@@ -80,7 +81,7 @@ export class WaitpointPresenter extends BasePresenter {
8081
return {
8182
id: waitpoint.friendlyId,
8283
type: waitpoint.type,
83-
status: waitpoint.outputIsError ? ("FAILED" as const) : waitpoint.status,
84+
status: waitpointStatusToApiStatus(waitpoint.status, waitpoint.outputIsError),
8485
idempotencyKey: waitpoint.idempotencyKey,
8586
userProvidedIdempotencyKey: waitpoint.userProvidedIdempotencyKey,
8687
idempotencyKeyExpiresAt: waitpoint.idempotencyKeyExpiresAt,

apps/webapp/app/presenters/v3/WaitpointTokenListPresenter.server.ts

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import parse from "parse-duration";
2-
import { Prisma, type WaitpointStatus } from "@trigger.dev/database";
2+
import {
3+
Prisma,
4+
type RunEngineVersion,
5+
type RuntimeEnvironmentType,
6+
type WaitpointStatus,
7+
} from "@trigger.dev/database";
38
import { type Direction } from "~/components/ListPagination";
49
import { sqlDatabaseSchema } from "~/db.server";
5-
import { type AuthenticatedEnvironment } from "~/services/apiAuth.server";
610
import { BasePresenter } from "./basePresenter.server";
711
import { type WaitpointSearchParams } from "~/components/runs/v3/WaitpointTokenFilters";
812
import { determineEngineVersion } from "~/v3/engineVersion.server";
@@ -11,7 +15,14 @@ import { type WaitpointTokenStatus, type WaitpointTokenItem } from "@trigger.dev
1115
const DEFAULT_PAGE_SIZE = 25;
1216

1317
export type WaitpointTokenListOptions = {
14-
environment: AuthenticatedEnvironment;
18+
environment: {
19+
id: string;
20+
type: RuntimeEnvironmentType;
21+
project: {
22+
id: string;
23+
engine: RunEngineVersion;
24+
};
25+
};
1526
// filters
1627
id?: string;
1728
statuses?: WaitpointTokenStatus[];
@@ -98,19 +109,19 @@ export class WaitpointTokenListPresenter extends BasePresenter {
98109
if (statuses?.length === 1) {
99110
if (statuses[0] === "COMPLETED") {
100111
filterOutputIsError = false;
101-
} else if (statuses[0] === "FAILED") {
112+
} else if (statuses[0] === "TIMED_OUT") {
102113
filterOutputIsError = true;
103114
}
104115
}
105116

106-
const statusesToFilter: WaitpointTokenStatus[] =
117+
const statusesToFilter: WaitpointStatus[] =
107118
statuses?.map((status) => {
108119
switch (status) {
109-
case "PENDING":
120+
case "WAITING":
110121
return "PENDING";
111122
case "COMPLETED":
112123
return "COMPLETED";
113-
case "FAILED":
124+
case "TIMED_OUT":
114125
return "COMPLETED";
115126
}
116127
}) ?? [];
@@ -235,7 +246,7 @@ export class WaitpointTokenListPresenter extends BasePresenter {
235246
success: true,
236247
tokens: tokensToReturn.map((token) => ({
237248
id: token.friendlyId,
238-
status: token.outputIsError ? "FAILED" : token.status,
249+
status: waitpointStatusToApiStatus(token.status, token.outputIsError),
239250
completedAt: token.completedAt ?? undefined,
240251
completedAfter: token.completedAfter ?? undefined,
241252
idempotencyKey: token.userProvidedIdempotencyKey
@@ -266,3 +277,15 @@ export class WaitpointTokenListPresenter extends BasePresenter {
266277
};
267278
}
268279
}
280+
281+
export function waitpointStatusToApiStatus(
282+
status: WaitpointStatus,
283+
outputIsError: boolean
284+
): WaitpointTokenStatus {
285+
switch (status) {
286+
case "PENDING":
287+
return "WAITING";
288+
case "COMPLETED":
289+
return outputIsError ? "TIMED_OUT" : "COMPLETED";
290+
}
291+
}

0 commit comments

Comments
 (0)