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