-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathuseWorkbenchProjection.ts
More file actions
102 lines (91 loc) · 2.31 KB
/
useWorkbenchProjection.ts
File metadata and controls
102 lines (91 loc) · 2.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import { useEffect, useReducer } from 'react';
import {
listApprovals,
listArtifacts,
listPreviews,
listProjects,
listRunners,
listRuns,
listThreads,
workbenchReducer,
type WorkbenchState,
} from '@shared/index';
const initialWorkbenchProjectionState: WorkbenchState = {
projects: [],
threads: [],
runners: [],
runs: [],
threadItems: [],
approvals: [],
artifacts: [],
previews: [],
runLogs: {},
connection: { status: 'idle' },
lastSeq: 0,
};
function formatError(error: unknown) {
if (error instanceof Error) return error.message;
return String(error || 'Edge catalog unavailable');
}
function withTimeout<T>(promise: Promise<T>, timeoutMs = 2500): Promise<T> {
return new Promise((resolve, reject) => {
const timer = window.setTimeout(() => reject(new Error('Edge catalog did not respond.')), timeoutMs);
promise.then(
(value) => {
window.clearTimeout(timer);
resolve(value);
},
(error) => {
window.clearTimeout(timer);
reject(error);
},
);
});
}
export function useWorkbenchProjection() {
const [state, dispatch] = useReducer(
workbenchReducer,
initialWorkbenchProjectionState,
(initialState) => workbenchReducer(initialState, { type: 'connection.loading' }),
);
useEffect(() => {
let cancelled = false;
async function loadSnapshot() {
dispatch({ type: 'connection.loading' });
try {
const [projects, threads, runners, runs, approvals, artifacts, previews] =
await withTimeout(Promise.all([
listProjects({ pageSize: 50 }),
listThreads({ pageSize: 50 }),
listRunners(),
listRuns({ pageSize: 50 }),
listApprovals(),
listArtifacts(),
listPreviews(),
]));
if (cancelled) return;
dispatch({
type: 'snapshot.loaded',
snapshot: {
projects,
threads,
runners,
runs,
approvals,
artifacts,
previews,
},
});
} catch (error) {
if (!cancelled) {
dispatch({ type: 'connection.error', error: formatError(error) });
}
}
}
loadSnapshot();
return () => {
cancelled = true;
};
}, []);
return state;
}