@coji/durably-react 0.6.0 → 0.7.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/dist/chunk-42AVE35N.js +142 -0
- package/dist/chunk-42AVE35N.js.map +1 -0
- package/dist/client.d.ts +31 -60
- package/dist/client.js +102 -131
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +31 -19
- package/dist/index.js +272 -249
- package/dist/index.js.map +1 -1
- package/dist/types-DY4Y6ggJ.d.ts +111 -0
- package/package.json +2 -2
- package/dist/types-BDUvsa8u.d.ts +0 -67
package/dist/index.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
initialSubscriptionState,
|
|
3
|
+
isJobDefinition,
|
|
4
|
+
subscriptionReducer,
|
|
5
|
+
useSubscription
|
|
6
|
+
} from "./chunk-42AVE35N.js";
|
|
7
|
+
|
|
1
8
|
// src/context.tsx
|
|
2
9
|
import { Suspense, createContext, use, useContext } from "react";
|
|
3
10
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -29,176 +36,222 @@ function useDurably() {
|
|
|
29
36
|
}
|
|
30
37
|
|
|
31
38
|
// src/hooks/use-job.ts
|
|
32
|
-
import { useCallback, useEffect,
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
-
const [currentRunId, setCurrentRunId] = useState(
|
|
41
|
-
options?.initialRunId ?? null
|
|
42
|
-
);
|
|
43
|
-
const jobHandleRef = useRef(null);
|
|
44
|
-
const currentRunIdRef = useRef(currentRunId);
|
|
45
|
-
currentRunIdRef.current = currentRunId;
|
|
39
|
+
import { useCallback as useCallback2, useEffect as useEffect3, useMemo, useRef as useRef2 } from "react";
|
|
40
|
+
|
|
41
|
+
// src/hooks/use-auto-resume.ts
|
|
42
|
+
import { useEffect } from "react";
|
|
43
|
+
function useAutoResume(jobHandle, options, callbacks) {
|
|
44
|
+
const enabled = options.enabled !== false;
|
|
45
|
+
const skipIfInitialRunId = options.skipIfInitialRunId !== false;
|
|
46
|
+
const initialRunId = options.initialRunId;
|
|
46
47
|
useEffect(() => {
|
|
48
|
+
if (!jobHandle) return;
|
|
49
|
+
if (!enabled) return;
|
|
50
|
+
if (skipIfInitialRunId && initialRunId) return;
|
|
51
|
+
let cancelled = false;
|
|
52
|
+
const findActiveRun = async () => {
|
|
53
|
+
const runningRuns = await jobHandle.getRuns({ status: "running" });
|
|
54
|
+
if (cancelled) return;
|
|
55
|
+
if (runningRuns.length > 0) {
|
|
56
|
+
const run = runningRuns[0];
|
|
57
|
+
callbacks.onRunFound(run.id, run.status);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const pendingRuns = await jobHandle.getRuns({ status: "pending" });
|
|
61
|
+
if (cancelled) return;
|
|
62
|
+
if (pendingRuns.length > 0) {
|
|
63
|
+
const run = pendingRuns[0];
|
|
64
|
+
callbacks.onRunFound(run.id, run.status);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
findActiveRun();
|
|
68
|
+
return () => {
|
|
69
|
+
cancelled = true;
|
|
70
|
+
};
|
|
71
|
+
}, [jobHandle, enabled, skipIfInitialRunId, initialRunId, callbacks]);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// src/hooks/use-job-subscription.ts
|
|
75
|
+
import { useCallback, useEffect as useEffect2, useReducer, useRef } from "react";
|
|
76
|
+
function jobSubscriptionReducer(state, action) {
|
|
77
|
+
switch (action.type) {
|
|
78
|
+
case "set_run_id":
|
|
79
|
+
return { ...state, currentRunId: action.runId };
|
|
80
|
+
case "switch_to_run":
|
|
81
|
+
return {
|
|
82
|
+
...initialSubscriptionState,
|
|
83
|
+
currentRunId: action.runId,
|
|
84
|
+
status: "running"
|
|
85
|
+
};
|
|
86
|
+
case "reset":
|
|
87
|
+
return {
|
|
88
|
+
...initialSubscriptionState,
|
|
89
|
+
currentRunId: null
|
|
90
|
+
};
|
|
91
|
+
default:
|
|
92
|
+
return {
|
|
93
|
+
...subscriptionReducer(state, action),
|
|
94
|
+
currentRunId: state.currentRunId
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function useJobSubscription(durably, jobName, options) {
|
|
99
|
+
const initialState = {
|
|
100
|
+
...initialSubscriptionState,
|
|
101
|
+
currentRunId: null
|
|
102
|
+
};
|
|
103
|
+
const [state, dispatch] = useReducer(
|
|
104
|
+
jobSubscriptionReducer,
|
|
105
|
+
initialState
|
|
106
|
+
);
|
|
107
|
+
const currentRunIdRef = useRef(null);
|
|
108
|
+
currentRunIdRef.current = state.currentRunId;
|
|
109
|
+
const followLatest = options?.followLatest !== false;
|
|
110
|
+
const maxLogs = options?.maxLogs ?? 0;
|
|
111
|
+
useEffect2(() => {
|
|
47
112
|
if (!durably) return;
|
|
48
|
-
const d = durably.register({
|
|
49
|
-
_job: jobDefinition
|
|
50
|
-
});
|
|
51
|
-
const jobHandle = d.jobs._job;
|
|
52
|
-
jobHandleRef.current = jobHandle;
|
|
53
113
|
const unsubscribes = [];
|
|
54
114
|
unsubscribes.push(
|
|
55
115
|
durably.on("run:start", (event) => {
|
|
56
|
-
if (event.jobName !==
|
|
57
|
-
if (
|
|
116
|
+
if (event.jobName !== jobName) return;
|
|
117
|
+
if (followLatest) {
|
|
118
|
+
dispatch({ type: "switch_to_run", runId: event.runId });
|
|
119
|
+
currentRunIdRef.current = event.runId;
|
|
120
|
+
} else {
|
|
58
121
|
if (event.runId !== currentRunIdRef.current) return;
|
|
59
|
-
|
|
60
|
-
return;
|
|
122
|
+
dispatch({ type: "run:start" });
|
|
61
123
|
}
|
|
62
|
-
setCurrentRunId(event.runId);
|
|
63
|
-
currentRunIdRef.current = event.runId;
|
|
64
|
-
setStatus("running");
|
|
65
|
-
setOutput(null);
|
|
66
|
-
setError(null);
|
|
67
|
-
setLogs([]);
|
|
68
|
-
setProgress(null);
|
|
69
124
|
})
|
|
70
125
|
);
|
|
71
126
|
unsubscribes.push(
|
|
72
127
|
durably.on("run:complete", (event) => {
|
|
73
128
|
if (event.runId !== currentRunIdRef.current) return;
|
|
74
|
-
|
|
75
|
-
setOutput(event.output);
|
|
129
|
+
dispatch({ type: "run:complete", output: event.output });
|
|
76
130
|
})
|
|
77
131
|
);
|
|
78
132
|
unsubscribes.push(
|
|
79
133
|
durably.on("run:fail", (event) => {
|
|
80
134
|
if (event.runId !== currentRunIdRef.current) return;
|
|
81
|
-
|
|
82
|
-
|
|
135
|
+
dispatch({ type: "run:fail", error: event.error });
|
|
136
|
+
})
|
|
137
|
+
);
|
|
138
|
+
unsubscribes.push(
|
|
139
|
+
durably.on("run:cancel", (event) => {
|
|
140
|
+
if (event.runId !== currentRunIdRef.current) return;
|
|
141
|
+
dispatch({ type: "run:cancel" });
|
|
142
|
+
})
|
|
143
|
+
);
|
|
144
|
+
unsubscribes.push(
|
|
145
|
+
durably.on("run:retry", (event) => {
|
|
146
|
+
if (event.runId !== currentRunIdRef.current) return;
|
|
147
|
+
dispatch({ type: "run:retry" });
|
|
83
148
|
})
|
|
84
149
|
);
|
|
85
150
|
unsubscribes.push(
|
|
86
151
|
durably.on("run:progress", (event) => {
|
|
87
152
|
if (event.runId !== currentRunIdRef.current) return;
|
|
88
|
-
|
|
153
|
+
dispatch({ type: "run:progress", progress: event.progress });
|
|
89
154
|
})
|
|
90
155
|
);
|
|
91
156
|
unsubscribes.push(
|
|
92
157
|
durably.on("log:write", (event) => {
|
|
93
158
|
if (event.runId !== currentRunIdRef.current) return;
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
104
|
-
}
|
|
105
|
-
]);
|
|
159
|
+
dispatch({
|
|
160
|
+
type: "log:write",
|
|
161
|
+
runId: event.runId,
|
|
162
|
+
stepName: event.stepName,
|
|
163
|
+
level: event.level,
|
|
164
|
+
message: event.message,
|
|
165
|
+
data: event.data,
|
|
166
|
+
maxLogs
|
|
167
|
+
});
|
|
106
168
|
})
|
|
107
169
|
);
|
|
108
|
-
if (options?.initialRunId && currentRunIdRef.current) {
|
|
109
|
-
jobHandle.getRun(currentRunIdRef.current).then((run) => {
|
|
110
|
-
if (run) {
|
|
111
|
-
setStatus(run.status);
|
|
112
|
-
if (run.status === "completed" && run.output) {
|
|
113
|
-
setOutput(run.output);
|
|
114
|
-
}
|
|
115
|
-
if (run.status === "failed" && run.error) {
|
|
116
|
-
setError(run.error);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
if (options?.autoResume !== false && !options?.initialRunId) {
|
|
122
|
-
;
|
|
123
|
-
(async () => {
|
|
124
|
-
const runningRuns = await jobHandle.getRuns({ status: "running" });
|
|
125
|
-
if (runningRuns.length > 0) {
|
|
126
|
-
const run = runningRuns[0];
|
|
127
|
-
setCurrentRunId(run.id);
|
|
128
|
-
currentRunIdRef.current = run.id;
|
|
129
|
-
setStatus(run.status);
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
const pendingRuns = await jobHandle.getRuns({ status: "pending" });
|
|
133
|
-
if (pendingRuns.length > 0) {
|
|
134
|
-
const run = pendingRuns[0];
|
|
135
|
-
setCurrentRunId(run.id);
|
|
136
|
-
currentRunIdRef.current = run.id;
|
|
137
|
-
setStatus(run.status);
|
|
138
|
-
}
|
|
139
|
-
})();
|
|
140
|
-
}
|
|
141
170
|
return () => {
|
|
142
171
|
for (const unsubscribe of unsubscribes) {
|
|
143
172
|
unsubscribe();
|
|
144
173
|
}
|
|
145
174
|
};
|
|
146
|
-
}, [
|
|
175
|
+
}, [durably, jobName, followLatest, maxLogs]);
|
|
176
|
+
const setCurrentRunId = useCallback((runId) => {
|
|
177
|
+
dispatch({ type: "set_run_id", runId });
|
|
178
|
+
currentRunIdRef.current = runId;
|
|
179
|
+
}, []);
|
|
180
|
+
const clearLogs = useCallback(() => {
|
|
181
|
+
dispatch({ type: "clear_logs" });
|
|
182
|
+
}, []);
|
|
183
|
+
const reset = useCallback(() => {
|
|
184
|
+
dispatch({ type: "reset" });
|
|
185
|
+
currentRunIdRef.current = null;
|
|
186
|
+
}, []);
|
|
187
|
+
return {
|
|
188
|
+
...state,
|
|
189
|
+
setCurrentRunId,
|
|
190
|
+
clearLogs,
|
|
191
|
+
reset
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// src/hooks/use-job.ts
|
|
196
|
+
function useJob(jobDefinition, options) {
|
|
197
|
+
const { durably } = useDurably();
|
|
198
|
+
const jobHandleRef = useRef2(null);
|
|
199
|
+
useEffect3(() => {
|
|
200
|
+
if (!durably) return;
|
|
201
|
+
const d = durably.register({
|
|
202
|
+
_job: jobDefinition
|
|
203
|
+
});
|
|
204
|
+
jobHandleRef.current = d.jobs._job;
|
|
205
|
+
}, [durably, jobDefinition]);
|
|
206
|
+
const subscription = useJobSubscription(
|
|
147
207
|
durably,
|
|
148
|
-
jobDefinition,
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
options?.followLatest
|
|
152
|
-
]);
|
|
153
|
-
useEffect(() => {
|
|
154
|
-
if (!durably || !currentRunId) return;
|
|
155
|
-
const jobHandle = jobHandleRef.current;
|
|
156
|
-
if (jobHandle && options?.initialRunId) {
|
|
157
|
-
jobHandle.getRun(currentRunId).then((run) => {
|
|
158
|
-
if (run) {
|
|
159
|
-
setStatus(run.status);
|
|
160
|
-
if (run.status === "completed" && run.output) {
|
|
161
|
-
setOutput(run.output);
|
|
162
|
-
}
|
|
163
|
-
if (run.status === "failed" && run.error) {
|
|
164
|
-
setError(run.error);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
});
|
|
208
|
+
jobDefinition.name,
|
|
209
|
+
{
|
|
210
|
+
followLatest: options?.followLatest
|
|
168
211
|
}
|
|
169
|
-
|
|
170
|
-
const
|
|
212
|
+
);
|
|
213
|
+
const autoResumeCallbacks = useMemo(
|
|
214
|
+
() => ({
|
|
215
|
+
onRunFound: (runId, _status) => {
|
|
216
|
+
subscription.setCurrentRunId(runId);
|
|
217
|
+
}
|
|
218
|
+
}),
|
|
219
|
+
[subscription.setCurrentRunId]
|
|
220
|
+
);
|
|
221
|
+
useAutoResume(
|
|
222
|
+
jobHandleRef.current,
|
|
223
|
+
{
|
|
224
|
+
enabled: options?.autoResume,
|
|
225
|
+
initialRunId: options?.initialRunId
|
|
226
|
+
},
|
|
227
|
+
autoResumeCallbacks
|
|
228
|
+
);
|
|
229
|
+
useEffect3(() => {
|
|
230
|
+
if (!durably || !options?.initialRunId) return;
|
|
231
|
+
subscription.setCurrentRunId(options.initialRunId);
|
|
232
|
+
}, [durably, options?.initialRunId, subscription.setCurrentRunId]);
|
|
233
|
+
const trigger = useCallback2(
|
|
171
234
|
async (input) => {
|
|
172
235
|
const jobHandle = jobHandleRef.current;
|
|
173
236
|
if (!jobHandle) {
|
|
174
237
|
throw new Error("Job not ready");
|
|
175
238
|
}
|
|
176
|
-
|
|
177
|
-
setError(null);
|
|
178
|
-
setLogs([]);
|
|
179
|
-
setProgress(null);
|
|
239
|
+
subscription.reset();
|
|
180
240
|
const run = await jobHandle.trigger(input);
|
|
181
|
-
setCurrentRunId(run.id);
|
|
182
|
-
currentRunIdRef.current = run.id;
|
|
183
|
-
setStatus("pending");
|
|
241
|
+
subscription.setCurrentRunId(run.id);
|
|
184
242
|
return { runId: run.id };
|
|
185
243
|
},
|
|
186
|
-
[]
|
|
244
|
+
[subscription]
|
|
187
245
|
);
|
|
188
|
-
const triggerAndWait =
|
|
246
|
+
const triggerAndWait = useCallback2(
|
|
189
247
|
async (input) => {
|
|
190
248
|
const jobHandle = jobHandleRef.current;
|
|
191
249
|
if (!jobHandle || !durably) {
|
|
192
250
|
throw new Error("Job not ready");
|
|
193
251
|
}
|
|
194
|
-
|
|
195
|
-
setError(null);
|
|
196
|
-
setLogs([]);
|
|
197
|
-
setProgress(null);
|
|
252
|
+
subscription.reset();
|
|
198
253
|
const run = await jobHandle.trigger(input);
|
|
199
|
-
setCurrentRunId(run.id);
|
|
200
|
-
currentRunIdRef.current = run.id;
|
|
201
|
-
setStatus("pending");
|
|
254
|
+
subscription.setCurrentRunId(run.id);
|
|
202
255
|
return new Promise((resolve, reject) => {
|
|
203
256
|
const checkCompletion = async () => {
|
|
204
257
|
const updatedRun = await jobHandle.getRun(run.id);
|
|
@@ -219,135 +272,101 @@ function useJob(jobDefinition, options) {
|
|
|
219
272
|
checkCompletion();
|
|
220
273
|
});
|
|
221
274
|
},
|
|
222
|
-
[durably]
|
|
275
|
+
[durably, subscription]
|
|
223
276
|
);
|
|
224
|
-
const reset = useCallback(() => {
|
|
225
|
-
setStatus(null);
|
|
226
|
-
setOutput(null);
|
|
227
|
-
setError(null);
|
|
228
|
-
setLogs([]);
|
|
229
|
-
setProgress(null);
|
|
230
|
-
setCurrentRunId(null);
|
|
231
|
-
}, []);
|
|
232
277
|
return {
|
|
233
278
|
trigger,
|
|
234
279
|
triggerAndWait,
|
|
235
|
-
status,
|
|
236
|
-
output,
|
|
237
|
-
error,
|
|
238
|
-
logs,
|
|
239
|
-
progress,
|
|
240
|
-
isRunning: status === "running",
|
|
241
|
-
isPending: status === "pending",
|
|
242
|
-
isCompleted: status === "completed",
|
|
243
|
-
isFailed: status === "failed",
|
|
244
|
-
isCancelled: status === "cancelled",
|
|
245
|
-
currentRunId,
|
|
246
|
-
reset
|
|
280
|
+
status: subscription.status,
|
|
281
|
+
output: subscription.output,
|
|
282
|
+
error: subscription.error,
|
|
283
|
+
logs: subscription.logs,
|
|
284
|
+
progress: subscription.progress,
|
|
285
|
+
isRunning: subscription.status === "running",
|
|
286
|
+
isPending: subscription.status === "pending",
|
|
287
|
+
isCompleted: subscription.status === "completed",
|
|
288
|
+
isFailed: subscription.status === "failed",
|
|
289
|
+
isCancelled: subscription.status === "cancelled",
|
|
290
|
+
currentRunId: subscription.currentRunId,
|
|
291
|
+
reset: subscription.reset
|
|
247
292
|
};
|
|
248
293
|
}
|
|
249
294
|
|
|
250
295
|
// src/hooks/use-run-subscription.ts
|
|
251
|
-
import {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
if (event.runId !== runIdRef.current) return;
|
|
300
|
-
setProgress(event.progress);
|
|
301
|
-
})
|
|
302
|
-
);
|
|
303
|
-
unsubscribes.push(
|
|
304
|
-
durably.on("log:write", (event) => {
|
|
305
|
-
if (event.runId !== runIdRef.current) return;
|
|
306
|
-
setLogs((prev) => {
|
|
307
|
-
const newLog = {
|
|
308
|
-
id: crypto.randomUUID(),
|
|
296
|
+
import { useMemo as useMemo2 } from "react";
|
|
297
|
+
|
|
298
|
+
// src/shared/durably-event-subscriber.ts
|
|
299
|
+
function createDurablyEventSubscriber(durably) {
|
|
300
|
+
return {
|
|
301
|
+
subscribe(runId, onEvent) {
|
|
302
|
+
const unsubscribes = [];
|
|
303
|
+
unsubscribes.push(
|
|
304
|
+
durably.on("run:start", (event) => {
|
|
305
|
+
if (event.runId !== runId) return;
|
|
306
|
+
onEvent({ type: "run:start" });
|
|
307
|
+
})
|
|
308
|
+
);
|
|
309
|
+
unsubscribes.push(
|
|
310
|
+
durably.on("run:complete", (event) => {
|
|
311
|
+
if (event.runId !== runId) return;
|
|
312
|
+
onEvent({ type: "run:complete", output: event.output });
|
|
313
|
+
})
|
|
314
|
+
);
|
|
315
|
+
unsubscribes.push(
|
|
316
|
+
durably.on("run:fail", (event) => {
|
|
317
|
+
if (event.runId !== runId) return;
|
|
318
|
+
onEvent({ type: "run:fail", error: event.error });
|
|
319
|
+
})
|
|
320
|
+
);
|
|
321
|
+
unsubscribes.push(
|
|
322
|
+
durably.on("run:cancel", (event) => {
|
|
323
|
+
if (event.runId !== runId) return;
|
|
324
|
+
onEvent({ type: "run:cancel" });
|
|
325
|
+
})
|
|
326
|
+
);
|
|
327
|
+
unsubscribes.push(
|
|
328
|
+
durably.on("run:retry", (event) => {
|
|
329
|
+
if (event.runId !== runId) return;
|
|
330
|
+
onEvent({ type: "run:retry" });
|
|
331
|
+
})
|
|
332
|
+
);
|
|
333
|
+
unsubscribes.push(
|
|
334
|
+
durably.on("run:progress", (event) => {
|
|
335
|
+
if (event.runId !== runId) return;
|
|
336
|
+
onEvent({ type: "run:progress", progress: event.progress });
|
|
337
|
+
})
|
|
338
|
+
);
|
|
339
|
+
unsubscribes.push(
|
|
340
|
+
durably.on("log:write", (event) => {
|
|
341
|
+
if (event.runId !== runId) return;
|
|
342
|
+
onEvent({
|
|
343
|
+
type: "log:write",
|
|
309
344
|
runId: event.runId,
|
|
310
345
|
stepName: event.stepName,
|
|
311
346
|
level: event.level,
|
|
312
347
|
message: event.message,
|
|
313
|
-
data: event.data
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
);
|
|
324
|
-
return () => {
|
|
325
|
-
for (const unsubscribe of unsubscribes) {
|
|
326
|
-
unsubscribe();
|
|
327
|
-
}
|
|
328
|
-
};
|
|
329
|
-
}, [durably, runId, maxLogs]);
|
|
330
|
-
const clearLogs = () => {
|
|
331
|
-
setLogs([]);
|
|
332
|
-
};
|
|
333
|
-
const reset = () => {
|
|
334
|
-
setStatus(null);
|
|
335
|
-
setOutput(null);
|
|
336
|
-
setError(null);
|
|
337
|
-
setLogs([]);
|
|
338
|
-
setProgress(null);
|
|
339
|
-
};
|
|
340
|
-
return {
|
|
341
|
-
status,
|
|
342
|
-
output,
|
|
343
|
-
error,
|
|
344
|
-
logs,
|
|
345
|
-
progress,
|
|
346
|
-
clearLogs,
|
|
347
|
-
reset
|
|
348
|
+
data: event.data
|
|
349
|
+
});
|
|
350
|
+
})
|
|
351
|
+
);
|
|
352
|
+
return () => {
|
|
353
|
+
for (const unsubscribe of unsubscribes) {
|
|
354
|
+
unsubscribe();
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
}
|
|
348
358
|
};
|
|
349
359
|
}
|
|
350
360
|
|
|
361
|
+
// src/hooks/use-run-subscription.ts
|
|
362
|
+
function useRunSubscription(durably, runId, options) {
|
|
363
|
+
const subscriber = useMemo2(
|
|
364
|
+
() => durably ? createDurablyEventSubscriber(durably) : null,
|
|
365
|
+
[durably]
|
|
366
|
+
);
|
|
367
|
+
return useSubscription(subscriber, runId, options);
|
|
368
|
+
}
|
|
369
|
+
|
|
351
370
|
// src/hooks/use-job-logs.ts
|
|
352
371
|
function useJobLogs(options) {
|
|
353
372
|
const { durably } = useDurably();
|
|
@@ -360,13 +379,13 @@ function useJobLogs(options) {
|
|
|
360
379
|
}
|
|
361
380
|
|
|
362
381
|
// src/hooks/use-job-run.ts
|
|
363
|
-
import { useEffect as
|
|
382
|
+
import { useEffect as useEffect4, useRef as useRef3 } from "react";
|
|
364
383
|
function useJobRun(options) {
|
|
365
384
|
const { durably } = useDurably();
|
|
366
385
|
const { runId } = options;
|
|
367
386
|
const subscription = useRunSubscription(durably, runId);
|
|
368
387
|
const fetchedRef = useRef3(/* @__PURE__ */ new Set());
|
|
369
|
-
|
|
388
|
+
useEffect4(() => {
|
|
370
389
|
if (!durably || !runId || fetchedRef.current.has(runId)) return;
|
|
371
390
|
fetchedRef.current.add(runId);
|
|
372
391
|
}, [durably, runId]);
|
|
@@ -385,22 +404,26 @@ function useJobRun(options) {
|
|
|
385
404
|
}
|
|
386
405
|
|
|
387
406
|
// src/hooks/use-runs.ts
|
|
388
|
-
import { useCallback as
|
|
389
|
-
function useRuns(
|
|
407
|
+
import { useCallback as useCallback3, useEffect as useEffect5, useState } from "react";
|
|
408
|
+
function useRuns(jobDefinitionOrOptions, optionsArg) {
|
|
390
409
|
const { durably } = useDurably();
|
|
410
|
+
const isJob = isJobDefinition(jobDefinitionOrOptions);
|
|
411
|
+
const jobName = isJob ? jobDefinitionOrOptions.name : jobDefinitionOrOptions?.jobName;
|
|
412
|
+
const options = isJob ? optionsArg : jobDefinitionOrOptions;
|
|
391
413
|
const pageSize = options?.pageSize ?? 10;
|
|
392
414
|
const realtime = options?.realtime ?? true;
|
|
393
|
-
const
|
|
394
|
-
const [
|
|
395
|
-
const [
|
|
396
|
-
const [
|
|
397
|
-
const
|
|
415
|
+
const status = options?.status;
|
|
416
|
+
const [runs, setRuns] = useState([]);
|
|
417
|
+
const [page, setPage] = useState(0);
|
|
418
|
+
const [hasMore, setHasMore] = useState(false);
|
|
419
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
420
|
+
const refresh = useCallback3(async () => {
|
|
398
421
|
if (!durably) return;
|
|
399
422
|
setIsLoading(true);
|
|
400
423
|
try {
|
|
401
424
|
const data = await durably.getRuns({
|
|
402
|
-
jobName
|
|
403
|
-
status
|
|
425
|
+
jobName,
|
|
426
|
+
status,
|
|
404
427
|
limit: pageSize + 1,
|
|
405
428
|
offset: page * pageSize
|
|
406
429
|
});
|
|
@@ -409,8 +432,8 @@ function useRuns(options) {
|
|
|
409
432
|
} finally {
|
|
410
433
|
setIsLoading(false);
|
|
411
434
|
}
|
|
412
|
-
}, [durably,
|
|
413
|
-
|
|
435
|
+
}, [durably, jobName, status, pageSize, page]);
|
|
436
|
+
useEffect5(() => {
|
|
414
437
|
if (!durably) return;
|
|
415
438
|
refresh();
|
|
416
439
|
if (!realtime) return;
|
|
@@ -431,15 +454,15 @@ function useRuns(options) {
|
|
|
431
454
|
}
|
|
432
455
|
};
|
|
433
456
|
}, [durably, refresh, realtime]);
|
|
434
|
-
const nextPage =
|
|
457
|
+
const nextPage = useCallback3(() => {
|
|
435
458
|
if (hasMore) {
|
|
436
459
|
setPage((p) => p + 1);
|
|
437
460
|
}
|
|
438
461
|
}, [hasMore]);
|
|
439
|
-
const prevPage =
|
|
462
|
+
const prevPage = useCallback3(() => {
|
|
440
463
|
setPage((p) => Math.max(0, p - 1));
|
|
441
464
|
}, []);
|
|
442
|
-
const goToPage =
|
|
465
|
+
const goToPage = useCallback3((newPage) => {
|
|
443
466
|
setPage(Math.max(0, newPage));
|
|
444
467
|
}, []);
|
|
445
468
|
return {
|