@coji/durably-react 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -47
- package/dist/index.d.ts +296 -76
- package/dist/index.js +555 -397
- package/dist/index.js.map +1 -1
- package/dist/spa.d.ts +301 -0
- package/dist/spa.js +501 -0
- package/dist/spa.js.map +1 -0
- package/dist/{types-xrRs7jov.d.ts → types-JIBwGTm6.d.ts} +2 -2
- package/package.json +6 -6
- package/dist/client.d.ts +0 -515
- package/dist/client.js +0 -629
- package/dist/client.js.map +0 -1
package/dist/client.js
DELETED
|
@@ -1,629 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
isJobDefinition,
|
|
3
|
-
useSubscription
|
|
4
|
-
} from "./chunk-XRJEZWAV.js";
|
|
5
|
-
|
|
6
|
-
// src/client/use-job.ts
|
|
7
|
-
import { useCallback, useEffect, useRef, useState } from "react";
|
|
8
|
-
|
|
9
|
-
// src/client/use-sse-subscription.ts
|
|
10
|
-
import { useMemo } from "react";
|
|
11
|
-
|
|
12
|
-
// src/shared/sse-event-subscriber.ts
|
|
13
|
-
function createSSEEventSubscriber(apiBaseUrl) {
|
|
14
|
-
return {
|
|
15
|
-
subscribe(runId, onEvent) {
|
|
16
|
-
const url = `${apiBaseUrl}/subscribe?runId=${encodeURIComponent(runId)}`;
|
|
17
|
-
const eventSource = new EventSource(url);
|
|
18
|
-
eventSource.onmessage = (messageEvent) => {
|
|
19
|
-
try {
|
|
20
|
-
const data = JSON.parse(messageEvent.data);
|
|
21
|
-
if (data.runId !== runId) return;
|
|
22
|
-
switch (data.type) {
|
|
23
|
-
case "run:start":
|
|
24
|
-
onEvent({ type: "run:start" });
|
|
25
|
-
break;
|
|
26
|
-
case "run:complete":
|
|
27
|
-
onEvent({
|
|
28
|
-
type: "run:complete",
|
|
29
|
-
output: data.output
|
|
30
|
-
});
|
|
31
|
-
break;
|
|
32
|
-
case "run:fail":
|
|
33
|
-
onEvent({ type: "run:fail", error: data.error });
|
|
34
|
-
break;
|
|
35
|
-
case "run:cancel":
|
|
36
|
-
onEvent({ type: "run:cancel" });
|
|
37
|
-
break;
|
|
38
|
-
case "run:retry":
|
|
39
|
-
onEvent({ type: "run:retry" });
|
|
40
|
-
break;
|
|
41
|
-
case "run:progress":
|
|
42
|
-
onEvent({ type: "run:progress", progress: data.progress });
|
|
43
|
-
break;
|
|
44
|
-
case "log:write":
|
|
45
|
-
onEvent({
|
|
46
|
-
type: "log:write",
|
|
47
|
-
runId: data.runId,
|
|
48
|
-
stepName: null,
|
|
49
|
-
level: data.level,
|
|
50
|
-
message: data.message,
|
|
51
|
-
data: data.data
|
|
52
|
-
});
|
|
53
|
-
break;
|
|
54
|
-
}
|
|
55
|
-
} catch {
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
eventSource.onerror = () => {
|
|
59
|
-
onEvent({ type: "connection_error", error: "Connection failed" });
|
|
60
|
-
eventSource.close();
|
|
61
|
-
};
|
|
62
|
-
return () => {
|
|
63
|
-
eventSource.close();
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// src/client/use-sse-subscription.ts
|
|
70
|
-
function useSSESubscription(api, runId, options) {
|
|
71
|
-
const subscriber = useMemo(
|
|
72
|
-
() => api ? createSSEEventSubscriber(api) : null,
|
|
73
|
-
[api]
|
|
74
|
-
);
|
|
75
|
-
return useSubscription(subscriber, runId, options);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// src/client/use-job.ts
|
|
79
|
-
function useJob(options) {
|
|
80
|
-
const {
|
|
81
|
-
api,
|
|
82
|
-
jobName,
|
|
83
|
-
initialRunId,
|
|
84
|
-
autoResume = true,
|
|
85
|
-
followLatest = true
|
|
86
|
-
} = options;
|
|
87
|
-
const [currentRunId, setCurrentRunId] = useState(
|
|
88
|
-
initialRunId ?? null
|
|
89
|
-
);
|
|
90
|
-
const [isPending, setIsPending] = useState(false);
|
|
91
|
-
const hasUserTriggered = useRef(false);
|
|
92
|
-
const subscription = useSSESubscription(api, currentRunId);
|
|
93
|
-
useEffect(() => {
|
|
94
|
-
if (!autoResume) return;
|
|
95
|
-
if (initialRunId) return;
|
|
96
|
-
const abortController = new AbortController();
|
|
97
|
-
const findActiveRun = async () => {
|
|
98
|
-
const runningParams = new URLSearchParams({
|
|
99
|
-
jobName,
|
|
100
|
-
status: "running",
|
|
101
|
-
limit: "1"
|
|
102
|
-
});
|
|
103
|
-
const runningRes = await fetch(`${api}/runs?${runningParams}`, {
|
|
104
|
-
signal: abortController.signal
|
|
105
|
-
});
|
|
106
|
-
if (runningRes.ok) {
|
|
107
|
-
const runs = await runningRes.json();
|
|
108
|
-
if (runs.length > 0) {
|
|
109
|
-
if (hasUserTriggered.current) return;
|
|
110
|
-
setCurrentRunId(runs[0].id);
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
const pendingParams = new URLSearchParams({
|
|
115
|
-
jobName,
|
|
116
|
-
status: "pending",
|
|
117
|
-
limit: "1"
|
|
118
|
-
});
|
|
119
|
-
const pendingRes = await fetch(`${api}/runs?${pendingParams}`, {
|
|
120
|
-
signal: abortController.signal
|
|
121
|
-
});
|
|
122
|
-
if (pendingRes.ok) {
|
|
123
|
-
const runs = await pendingRes.json();
|
|
124
|
-
if (runs.length > 0) {
|
|
125
|
-
if (hasUserTriggered.current) return;
|
|
126
|
-
setCurrentRunId(runs[0].id);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
findActiveRun().catch((err) => {
|
|
131
|
-
if (err.name !== "AbortError") {
|
|
132
|
-
console.error("autoResume error:", err);
|
|
133
|
-
}
|
|
134
|
-
});
|
|
135
|
-
return () => {
|
|
136
|
-
abortController.abort();
|
|
137
|
-
};
|
|
138
|
-
}, [api, jobName, autoResume, initialRunId]);
|
|
139
|
-
useEffect(() => {
|
|
140
|
-
if (!followLatest) return;
|
|
141
|
-
const params = new URLSearchParams({ jobName });
|
|
142
|
-
const eventSource = new EventSource(`${api}/runs/subscribe?${params}`);
|
|
143
|
-
eventSource.onmessage = (event) => {
|
|
144
|
-
try {
|
|
145
|
-
const data = JSON.parse(event.data);
|
|
146
|
-
if ((data.type === "run:trigger" || data.type === "run:start") && data.runId) {
|
|
147
|
-
setCurrentRunId(data.runId);
|
|
148
|
-
}
|
|
149
|
-
} catch {
|
|
150
|
-
}
|
|
151
|
-
};
|
|
152
|
-
eventSource.onerror = () => {
|
|
153
|
-
};
|
|
154
|
-
return () => {
|
|
155
|
-
eventSource.close();
|
|
156
|
-
};
|
|
157
|
-
}, [api, jobName, followLatest]);
|
|
158
|
-
const trigger = useCallback(
|
|
159
|
-
async (input) => {
|
|
160
|
-
hasUserTriggered.current = true;
|
|
161
|
-
subscription.reset();
|
|
162
|
-
setIsPending(true);
|
|
163
|
-
const response = await fetch(`${api}/trigger`, {
|
|
164
|
-
method: "POST",
|
|
165
|
-
headers: {
|
|
166
|
-
"Content-Type": "application/json"
|
|
167
|
-
},
|
|
168
|
-
body: JSON.stringify({ jobName, input })
|
|
169
|
-
});
|
|
170
|
-
if (!response.ok) {
|
|
171
|
-
setIsPending(false);
|
|
172
|
-
const errorText = await response.text();
|
|
173
|
-
throw new Error(errorText || `HTTP ${response.status}`);
|
|
174
|
-
}
|
|
175
|
-
const { runId } = await response.json();
|
|
176
|
-
setCurrentRunId(runId);
|
|
177
|
-
return { runId };
|
|
178
|
-
},
|
|
179
|
-
[api, jobName, subscription.reset]
|
|
180
|
-
);
|
|
181
|
-
const triggerAndWait = useCallback(
|
|
182
|
-
async (input) => {
|
|
183
|
-
const { runId } = await trigger(input);
|
|
184
|
-
return new Promise((resolve, reject) => {
|
|
185
|
-
const checkInterval = setInterval(() => {
|
|
186
|
-
if (subscription.status === "completed" && subscription.output) {
|
|
187
|
-
clearInterval(checkInterval);
|
|
188
|
-
resolve({ runId, output: subscription.output });
|
|
189
|
-
} else if (subscription.status === "failed") {
|
|
190
|
-
clearInterval(checkInterval);
|
|
191
|
-
reject(new Error(subscription.error ?? "Job failed"));
|
|
192
|
-
} else if (subscription.status === "cancelled") {
|
|
193
|
-
clearInterval(checkInterval);
|
|
194
|
-
reject(new Error("Job cancelled"));
|
|
195
|
-
}
|
|
196
|
-
}, 50);
|
|
197
|
-
});
|
|
198
|
-
},
|
|
199
|
-
[trigger, subscription.status, subscription.output, subscription.error]
|
|
200
|
-
);
|
|
201
|
-
const reset = useCallback(() => {
|
|
202
|
-
subscription.reset();
|
|
203
|
-
setCurrentRunId(null);
|
|
204
|
-
setIsPending(false);
|
|
205
|
-
}, [subscription.reset]);
|
|
206
|
-
const effectiveStatus = subscription.status ?? (isPending ? "pending" : null);
|
|
207
|
-
useEffect(() => {
|
|
208
|
-
if (subscription.status && isPending) {
|
|
209
|
-
setIsPending(false);
|
|
210
|
-
}
|
|
211
|
-
}, [subscription.status, isPending]);
|
|
212
|
-
return {
|
|
213
|
-
trigger,
|
|
214
|
-
triggerAndWait,
|
|
215
|
-
status: effectiveStatus,
|
|
216
|
-
output: subscription.output,
|
|
217
|
-
error: subscription.error,
|
|
218
|
-
logs: subscription.logs,
|
|
219
|
-
progress: subscription.progress,
|
|
220
|
-
isRunning: effectiveStatus === "running",
|
|
221
|
-
isPending: effectiveStatus === "pending",
|
|
222
|
-
isCompleted: effectiveStatus === "completed",
|
|
223
|
-
isFailed: effectiveStatus === "failed",
|
|
224
|
-
isCancelled: effectiveStatus === "cancelled",
|
|
225
|
-
currentRunId,
|
|
226
|
-
reset
|
|
227
|
-
};
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// src/client/use-job-logs.ts
|
|
231
|
-
function useJobLogs(options) {
|
|
232
|
-
const { api, runId, maxLogs } = options;
|
|
233
|
-
const subscription = useSSESubscription(api, runId, { maxLogs });
|
|
234
|
-
return {
|
|
235
|
-
logs: subscription.logs,
|
|
236
|
-
clearLogs: subscription.clearLogs
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
// src/client/use-job-run.ts
|
|
241
|
-
import { useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
242
|
-
function useJobRun(options) {
|
|
243
|
-
const { api, runId, onStart, onComplete, onFail } = options;
|
|
244
|
-
const subscription = useSSESubscription(api, runId);
|
|
245
|
-
const effectiveStatus = subscription.status ?? (runId ? "pending" : null);
|
|
246
|
-
const isCompleted = effectiveStatus === "completed";
|
|
247
|
-
const isFailed = effectiveStatus === "failed";
|
|
248
|
-
const isPending = effectiveStatus === "pending";
|
|
249
|
-
const isRunning = effectiveStatus === "running";
|
|
250
|
-
const isCancelled = effectiveStatus === "cancelled";
|
|
251
|
-
const prevStatusRef = useRef2(null);
|
|
252
|
-
useEffect2(() => {
|
|
253
|
-
const prevStatus = prevStatusRef.current;
|
|
254
|
-
prevStatusRef.current = effectiveStatus;
|
|
255
|
-
if (prevStatus !== effectiveStatus) {
|
|
256
|
-
if (prevStatus === null && (isPending || isRunning) && onStart) {
|
|
257
|
-
onStart();
|
|
258
|
-
}
|
|
259
|
-
if (isCompleted && onComplete) {
|
|
260
|
-
onComplete();
|
|
261
|
-
}
|
|
262
|
-
if (isFailed && onFail) {
|
|
263
|
-
onFail();
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
}, [
|
|
267
|
-
effectiveStatus,
|
|
268
|
-
isPending,
|
|
269
|
-
isRunning,
|
|
270
|
-
isCompleted,
|
|
271
|
-
isFailed,
|
|
272
|
-
onStart,
|
|
273
|
-
onComplete,
|
|
274
|
-
onFail
|
|
275
|
-
]);
|
|
276
|
-
return {
|
|
277
|
-
status: effectiveStatus,
|
|
278
|
-
output: subscription.output,
|
|
279
|
-
error: subscription.error,
|
|
280
|
-
logs: subscription.logs,
|
|
281
|
-
progress: subscription.progress,
|
|
282
|
-
isRunning,
|
|
283
|
-
isPending,
|
|
284
|
-
isCompleted,
|
|
285
|
-
isFailed,
|
|
286
|
-
isCancelled
|
|
287
|
-
};
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
// src/client/create-durably-client.ts
|
|
291
|
-
function createDurablyClient(options) {
|
|
292
|
-
const { api } = options;
|
|
293
|
-
return new Proxy({}, {
|
|
294
|
-
get(_target, jobKey) {
|
|
295
|
-
return {
|
|
296
|
-
useJob: () => {
|
|
297
|
-
return useJob({ api, jobName: jobKey });
|
|
298
|
-
},
|
|
299
|
-
useRun: (runId) => {
|
|
300
|
-
return useJobRun({ api, runId });
|
|
301
|
-
},
|
|
302
|
-
useLogs: (runId, logsOptions) => {
|
|
303
|
-
return useJobLogs({ api, runId, maxLogs: logsOptions?.maxLogs });
|
|
304
|
-
}
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
// src/client/create-job-hooks.ts
|
|
311
|
-
function createJobHooks(options) {
|
|
312
|
-
const { api, jobName } = options;
|
|
313
|
-
return {
|
|
314
|
-
useJob: () => {
|
|
315
|
-
return useJob({ api, jobName });
|
|
316
|
-
},
|
|
317
|
-
useRun: (runId) => {
|
|
318
|
-
return useJobRun({ api, runId });
|
|
319
|
-
},
|
|
320
|
-
useLogs: (runId, logsOptions) => {
|
|
321
|
-
return useJobLogs({ api, runId, maxLogs: logsOptions?.maxLogs });
|
|
322
|
-
}
|
|
323
|
-
};
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
// src/client/use-runs.ts
|
|
327
|
-
import { useCallback as useCallback2, useEffect as useEffect3, useMemo as useMemo2, useRef as useRef3, useState as useState2 } from "react";
|
|
328
|
-
function useRuns(jobDefinitionOrOptions, optionsArg) {
|
|
329
|
-
const isJob = isJobDefinition(jobDefinitionOrOptions);
|
|
330
|
-
const jobName = isJob ? jobDefinitionOrOptions.name : jobDefinitionOrOptions.jobName;
|
|
331
|
-
const options = isJob ? optionsArg : jobDefinitionOrOptions;
|
|
332
|
-
const { api, status, labels, pageSize = 10, realtime = true } = options;
|
|
333
|
-
const labelsKey = labels ? JSON.stringify(labels) : void 0;
|
|
334
|
-
const stableLabels = useMemo2(
|
|
335
|
-
() => labelsKey ? JSON.parse(labelsKey) : void 0,
|
|
336
|
-
[labelsKey]
|
|
337
|
-
);
|
|
338
|
-
const [runs, setRuns] = useState2([]);
|
|
339
|
-
const [page, setPage] = useState2(0);
|
|
340
|
-
const [hasMore, setHasMore] = useState2(false);
|
|
341
|
-
const [isLoading, setIsLoading] = useState2(true);
|
|
342
|
-
const [error, setError] = useState2(null);
|
|
343
|
-
const isMountedRef = useRef3(true);
|
|
344
|
-
const eventSourceRef = useRef3(null);
|
|
345
|
-
const refresh = useCallback2(async () => {
|
|
346
|
-
setIsLoading(true);
|
|
347
|
-
setError(null);
|
|
348
|
-
try {
|
|
349
|
-
const params = new URLSearchParams();
|
|
350
|
-
if (jobName) params.set("jobName", jobName);
|
|
351
|
-
if (status) params.set("status", status);
|
|
352
|
-
appendLabelsToParams(params, stableLabels);
|
|
353
|
-
params.set("limit", String(pageSize + 1));
|
|
354
|
-
params.set("offset", String(page * pageSize));
|
|
355
|
-
const url = `${api}/runs?${params.toString()}`;
|
|
356
|
-
const response = await fetch(url);
|
|
357
|
-
if (!response.ok) {
|
|
358
|
-
throw new Error(`Failed to fetch runs: ${response.statusText}`);
|
|
359
|
-
}
|
|
360
|
-
const data = await response.json();
|
|
361
|
-
if (isMountedRef.current) {
|
|
362
|
-
setHasMore(data.length > pageSize);
|
|
363
|
-
setRuns(data.slice(0, pageSize));
|
|
364
|
-
}
|
|
365
|
-
} catch (err) {
|
|
366
|
-
if (isMountedRef.current) {
|
|
367
|
-
setError(err instanceof Error ? err.message : "Unknown error");
|
|
368
|
-
}
|
|
369
|
-
} finally {
|
|
370
|
-
if (isMountedRef.current) {
|
|
371
|
-
setIsLoading(false);
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
}, [api, jobName, status, stableLabels, pageSize, page]);
|
|
375
|
-
useEffect3(() => {
|
|
376
|
-
isMountedRef.current = true;
|
|
377
|
-
refresh();
|
|
378
|
-
return () => {
|
|
379
|
-
isMountedRef.current = false;
|
|
380
|
-
};
|
|
381
|
-
}, [refresh]);
|
|
382
|
-
useEffect3(() => {
|
|
383
|
-
if (!realtime || page !== 0) {
|
|
384
|
-
if (eventSourceRef.current) {
|
|
385
|
-
eventSourceRef.current.close();
|
|
386
|
-
eventSourceRef.current = null;
|
|
387
|
-
}
|
|
388
|
-
return;
|
|
389
|
-
}
|
|
390
|
-
const params = new URLSearchParams();
|
|
391
|
-
if (jobName) params.set("jobName", jobName);
|
|
392
|
-
appendLabelsToParams(params, stableLabels);
|
|
393
|
-
const sseUrl = `${api}/runs/subscribe${params.toString() ? `?${params.toString()}` : ""}`;
|
|
394
|
-
const eventSource = new EventSource(sseUrl);
|
|
395
|
-
eventSourceRef.current = eventSource;
|
|
396
|
-
eventSource.onmessage = (event) => {
|
|
397
|
-
try {
|
|
398
|
-
const data = JSON.parse(event.data);
|
|
399
|
-
if (data.type === "run:trigger" || data.type === "run:start" || data.type === "run:complete" || data.type === "run:fail" || data.type === "run:cancel" || data.type === "run:delete" || data.type === "run:retry") {
|
|
400
|
-
refresh();
|
|
401
|
-
}
|
|
402
|
-
if (data.type === "run:progress") {
|
|
403
|
-
setRuns(
|
|
404
|
-
(prev) => prev.map(
|
|
405
|
-
(run) => run.id === data.runId ? { ...run, progress: data.progress } : run
|
|
406
|
-
)
|
|
407
|
-
);
|
|
408
|
-
}
|
|
409
|
-
if (data.type === "step:complete") {
|
|
410
|
-
setRuns(
|
|
411
|
-
(prev) => prev.map(
|
|
412
|
-
(run) => run.id === data.runId ? { ...run, currentStepIndex: data.stepIndex + 1 } : run
|
|
413
|
-
)
|
|
414
|
-
);
|
|
415
|
-
}
|
|
416
|
-
if (data.type === "step:start" || data.type === "step:fail" || data.type === "step:cancel") {
|
|
417
|
-
refresh();
|
|
418
|
-
}
|
|
419
|
-
} catch {
|
|
420
|
-
}
|
|
421
|
-
};
|
|
422
|
-
eventSource.onerror = () => {
|
|
423
|
-
};
|
|
424
|
-
return () => {
|
|
425
|
-
eventSource.close();
|
|
426
|
-
eventSourceRef.current = null;
|
|
427
|
-
};
|
|
428
|
-
}, [api, jobName, stableLabels, page, realtime, refresh]);
|
|
429
|
-
const nextPage = useCallback2(() => {
|
|
430
|
-
if (hasMore) {
|
|
431
|
-
setPage((p) => p + 1);
|
|
432
|
-
}
|
|
433
|
-
}, [hasMore]);
|
|
434
|
-
const prevPage = useCallback2(() => {
|
|
435
|
-
setPage((p) => Math.max(0, p - 1));
|
|
436
|
-
}, []);
|
|
437
|
-
const goToPage = useCallback2((newPage) => {
|
|
438
|
-
setPage(Math.max(0, newPage));
|
|
439
|
-
}, []);
|
|
440
|
-
return {
|
|
441
|
-
runs,
|
|
442
|
-
page,
|
|
443
|
-
hasMore,
|
|
444
|
-
isLoading,
|
|
445
|
-
error,
|
|
446
|
-
nextPage,
|
|
447
|
-
prevPage,
|
|
448
|
-
goToPage,
|
|
449
|
-
refresh
|
|
450
|
-
};
|
|
451
|
-
}
|
|
452
|
-
function appendLabelsToParams(params, labels) {
|
|
453
|
-
if (!labels) return;
|
|
454
|
-
for (const [key, value] of Object.entries(labels)) {
|
|
455
|
-
params.set(`label.${key}`, value);
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
// src/client/use-run-actions.ts
|
|
460
|
-
import { useCallback as useCallback3, useState as useState3 } from "react";
|
|
461
|
-
function useRunActions(options) {
|
|
462
|
-
const { api } = options;
|
|
463
|
-
const [isLoading, setIsLoading] = useState3(false);
|
|
464
|
-
const [error, setError] = useState3(null);
|
|
465
|
-
const retry = useCallback3(
|
|
466
|
-
async (runId) => {
|
|
467
|
-
setIsLoading(true);
|
|
468
|
-
setError(null);
|
|
469
|
-
try {
|
|
470
|
-
const url = `${api}/retry?runId=${encodeURIComponent(runId)}`;
|
|
471
|
-
const response = await fetch(url, { method: "POST" });
|
|
472
|
-
if (!response.ok) {
|
|
473
|
-
let errorMessage = `Failed to retry: ${response.statusText}`;
|
|
474
|
-
try {
|
|
475
|
-
const data = await response.json();
|
|
476
|
-
if (data.error) {
|
|
477
|
-
errorMessage = data.error;
|
|
478
|
-
}
|
|
479
|
-
} catch {
|
|
480
|
-
}
|
|
481
|
-
throw new Error(errorMessage);
|
|
482
|
-
}
|
|
483
|
-
} catch (err) {
|
|
484
|
-
const message = err instanceof Error ? err.message : "Unknown error";
|
|
485
|
-
setError(message);
|
|
486
|
-
throw err;
|
|
487
|
-
} finally {
|
|
488
|
-
setIsLoading(false);
|
|
489
|
-
}
|
|
490
|
-
},
|
|
491
|
-
[api]
|
|
492
|
-
);
|
|
493
|
-
const cancel = useCallback3(
|
|
494
|
-
async (runId) => {
|
|
495
|
-
setIsLoading(true);
|
|
496
|
-
setError(null);
|
|
497
|
-
try {
|
|
498
|
-
const url = `${api}/cancel?runId=${encodeURIComponent(runId)}`;
|
|
499
|
-
const response = await fetch(url, { method: "POST" });
|
|
500
|
-
if (!response.ok) {
|
|
501
|
-
let errorMessage = `Failed to cancel: ${response.statusText}`;
|
|
502
|
-
try {
|
|
503
|
-
const data = await response.json();
|
|
504
|
-
if (data.error) {
|
|
505
|
-
errorMessage = data.error;
|
|
506
|
-
}
|
|
507
|
-
} catch {
|
|
508
|
-
}
|
|
509
|
-
throw new Error(errorMessage);
|
|
510
|
-
}
|
|
511
|
-
} catch (err) {
|
|
512
|
-
const message = err instanceof Error ? err.message : "Unknown error";
|
|
513
|
-
setError(message);
|
|
514
|
-
throw err;
|
|
515
|
-
} finally {
|
|
516
|
-
setIsLoading(false);
|
|
517
|
-
}
|
|
518
|
-
},
|
|
519
|
-
[api]
|
|
520
|
-
);
|
|
521
|
-
const deleteRun = useCallback3(
|
|
522
|
-
async (runId) => {
|
|
523
|
-
setIsLoading(true);
|
|
524
|
-
setError(null);
|
|
525
|
-
try {
|
|
526
|
-
const url = `${api}/run?runId=${encodeURIComponent(runId)}`;
|
|
527
|
-
const response = await fetch(url, { method: "DELETE" });
|
|
528
|
-
if (!response.ok) {
|
|
529
|
-
let errorMessage = `Failed to delete: ${response.statusText}`;
|
|
530
|
-
try {
|
|
531
|
-
const data = await response.json();
|
|
532
|
-
if (data.error) {
|
|
533
|
-
errorMessage = data.error;
|
|
534
|
-
}
|
|
535
|
-
} catch {
|
|
536
|
-
}
|
|
537
|
-
throw new Error(errorMessage);
|
|
538
|
-
}
|
|
539
|
-
} catch (err) {
|
|
540
|
-
const message = err instanceof Error ? err.message : "Unknown error";
|
|
541
|
-
setError(message);
|
|
542
|
-
throw err;
|
|
543
|
-
} finally {
|
|
544
|
-
setIsLoading(false);
|
|
545
|
-
}
|
|
546
|
-
},
|
|
547
|
-
[api]
|
|
548
|
-
);
|
|
549
|
-
const getRun = useCallback3(
|
|
550
|
-
async (runId) => {
|
|
551
|
-
setIsLoading(true);
|
|
552
|
-
setError(null);
|
|
553
|
-
try {
|
|
554
|
-
const url = `${api}/run?runId=${encodeURIComponent(runId)}`;
|
|
555
|
-
const response = await fetch(url);
|
|
556
|
-
if (response.status === 404) {
|
|
557
|
-
return null;
|
|
558
|
-
}
|
|
559
|
-
if (!response.ok) {
|
|
560
|
-
let errorMessage = `Failed to get run: ${response.statusText}`;
|
|
561
|
-
try {
|
|
562
|
-
const data = await response.json();
|
|
563
|
-
if (data.error) {
|
|
564
|
-
errorMessage = data.error;
|
|
565
|
-
}
|
|
566
|
-
} catch {
|
|
567
|
-
}
|
|
568
|
-
throw new Error(errorMessage);
|
|
569
|
-
}
|
|
570
|
-
return await response.json();
|
|
571
|
-
} catch (err) {
|
|
572
|
-
const message = err instanceof Error ? err.message : "Unknown error";
|
|
573
|
-
setError(message);
|
|
574
|
-
throw err;
|
|
575
|
-
} finally {
|
|
576
|
-
setIsLoading(false);
|
|
577
|
-
}
|
|
578
|
-
},
|
|
579
|
-
[api]
|
|
580
|
-
);
|
|
581
|
-
const getSteps = useCallback3(
|
|
582
|
-
async (runId) => {
|
|
583
|
-
setIsLoading(true);
|
|
584
|
-
setError(null);
|
|
585
|
-
try {
|
|
586
|
-
const url = `${api}/steps?runId=${encodeURIComponent(runId)}`;
|
|
587
|
-
const response = await fetch(url);
|
|
588
|
-
if (!response.ok) {
|
|
589
|
-
let errorMessage = `Failed to get steps: ${response.statusText}`;
|
|
590
|
-
try {
|
|
591
|
-
const data = await response.json();
|
|
592
|
-
if (data.error) {
|
|
593
|
-
errorMessage = data.error;
|
|
594
|
-
}
|
|
595
|
-
} catch {
|
|
596
|
-
}
|
|
597
|
-
throw new Error(errorMessage);
|
|
598
|
-
}
|
|
599
|
-
return await response.json();
|
|
600
|
-
} catch (err) {
|
|
601
|
-
const message = err instanceof Error ? err.message : "Unknown error";
|
|
602
|
-
setError(message);
|
|
603
|
-
throw err;
|
|
604
|
-
} finally {
|
|
605
|
-
setIsLoading(false);
|
|
606
|
-
}
|
|
607
|
-
},
|
|
608
|
-
[api]
|
|
609
|
-
);
|
|
610
|
-
return {
|
|
611
|
-
retry,
|
|
612
|
-
cancel,
|
|
613
|
-
deleteRun,
|
|
614
|
-
getRun,
|
|
615
|
-
getSteps,
|
|
616
|
-
isLoading,
|
|
617
|
-
error
|
|
618
|
-
};
|
|
619
|
-
}
|
|
620
|
-
export {
|
|
621
|
-
createDurablyClient,
|
|
622
|
-
createJobHooks,
|
|
623
|
-
useJob,
|
|
624
|
-
useJobLogs,
|
|
625
|
-
useJobRun,
|
|
626
|
-
useRunActions,
|
|
627
|
-
useRuns
|
|
628
|
-
};
|
|
629
|
-
//# sourceMappingURL=client.js.map
|