causal-inspector 0.1.4 → 0.1.6
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/CausalInspector.css +447 -20
- package/dist/components/CopyablePayload.js +8 -8
- package/dist/components/FilterBar.js +9 -6
- package/dist/components/JsonSyntax.js +8 -8
- package/dist/engines/query.js +15 -13
- package/dist/events.d.ts +6 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/panes/CausalFlowPane.js +25 -21
- package/dist/panes/CausalTreePane.js +38 -13
- package/dist/panes/CorrelationExplorerPane.js +7 -2
- package/dist/panes/LogsPane.js +16 -7
- package/dist/panes/TimelinePane.js +20 -12
- package/dist/panes/WaterfallPane.js +181 -68
- package/dist/queries.d.ts +1 -0
- package/dist/queries.js +14 -0
- package/dist/reducer.js +5 -0
- package/dist/state.d.ts +2 -1
- package/dist/state.js +3 -0
- package/dist/theme.js +4 -3
- package/dist/types.d.ts +12 -4
- package/package.json +1 -1
|
@@ -4,16 +4,18 @@ import { useSelector, useDispatch } from "../machine";
|
|
|
4
4
|
import { FilterBar } from "../components/FilterBar";
|
|
5
5
|
import { CopyablePayload } from "../components/CopyablePayload";
|
|
6
6
|
import { eventTextColor, eventBg } from "../theme";
|
|
7
|
-
import { formatTs, compactPayload,
|
|
7
|
+
import { formatTs, compactPayload, inScrubberRange } from "../utils";
|
|
8
8
|
import { Search, ChevronRight } from "lucide-react";
|
|
9
|
-
function EventRow({ event, isSelected, onClick, onFilterCorrelation,
|
|
9
|
+
function EventRow({ event, isSelected, onClick, onFilterCorrelation, onInvestigate, }) {
|
|
10
10
|
const [payloadOpen, setPayloadOpen] = useState(false);
|
|
11
|
-
return (_jsxs("div", { className: `
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
return (_jsxs("div", { className: `ci-event-row${isSelected ? " ci-selected" : ""}`, children: [_jsx("div", { onClick: onClick, role: "button", tabIndex: 0, style: { width: "100%", textAlign: "left", cursor: "pointer" }, children: _jsxs("div", { className: "ci-row", style: { gap: 10, minWidth: 0 }, children: [_jsx("span", { className: "ci-mono ci-tabular", style: { fontSize: 10, color: "var(--ci-text-dim)", width: 40, flexShrink: 0, textAlign: "right" }, children: event.seq }), _jsx("span", { className: "ci-tabular", style: { fontSize: 10, color: "var(--ci-text-muted)", opacity: 0.7, flexShrink: 0, width: 128 }, children: formatTs(event.ts) }), event.correlationId && (_jsx("button", { onClick: (e) => { e.stopPropagation(); onFilterCorrelation(event.correlationId); }, className: "ci-corr-pill", title: `Filter by correlation ${event.correlationId}`, style: { flexShrink: 0 }, children: event.correlationId.slice(0, 8) })), _jsx("span", { className: "ci-mono", style: {
|
|
12
|
+
fontSize: 12,
|
|
13
|
+
flexShrink: 0,
|
|
14
|
+
padding: "2px 6px",
|
|
15
|
+
borderRadius: "var(--ci-radius-sm)",
|
|
14
16
|
color: eventTextColor(event.name),
|
|
15
17
|
background: eventBg(event.name),
|
|
16
|
-
}, children: event.name }), _jsxs("button", { onClick: (e) => { e.stopPropagation(); setPayloadOpen((v) => !v); }, className: "flex
|
|
18
|
+
}, children: event.name }), _jsxs("button", { onClick: (e) => { e.stopPropagation(); setPayloadOpen((v) => !v); }, className: "ci-mono ci-truncate", style: { display: "flex", alignItems: "center", gap: 4, fontSize: 10, color: "var(--ci-text-dim)", textAlign: "left", minWidth: 0, background: "none", border: "none", cursor: "pointer", transition: "color 150ms" }, title: "Click to expand payload", children: [_jsx(ChevronRight, { size: 10, style: { flexShrink: 0, transition: "transform 150ms", transform: payloadOpen ? "rotate(90deg)" : undefined } }), _jsx("span", { className: "ci-truncate", children: event.summary ?? compactPayload(event.payload) })] }), onInvestigate && (_jsx("button", { onClick: (e) => { e.stopPropagation(); onInvestigate(); }, className: "ci-copy-btn ci-btn", style: { marginLeft: "auto", flexShrink: 0 }, title: "Investigate", children: _jsx(Search, { size: 12 }) }))] }) }), payloadOpen && (_jsx("div", { style: { marginTop: 8, marginLeft: 48, maxHeight: 256 }, children: _jsx(CopyablePayload, { payload: event.payload }) }))] }));
|
|
17
19
|
}
|
|
18
20
|
function InfiniteScrollSentinel({ onVisible, loading }) {
|
|
19
21
|
const ref = useRef(null);
|
|
@@ -30,12 +32,21 @@ function InfiniteScrollSentinel({ onVisible, loading }) {
|
|
|
30
32
|
observer.observe(el);
|
|
31
33
|
return () => observer.disconnect();
|
|
32
34
|
}, [loading]);
|
|
33
|
-
return (_jsx("div", { ref: ref, className: "
|
|
35
|
+
return (_jsx("div", { ref: ref, className: "ci-row", style: { justifyContent: "center", padding: "16px 0" }, children: loading && (_jsxs("div", { className: "ci-row", style: { gap: 8 }, children: [_jsx("div", { className: "ci-pulse", style: { width: 6, height: 6, borderRadius: "50%", background: "rgba(99, 102, 241, 0.5)" } }), _jsx("span", { style: { fontSize: 10, color: "var(--ci-text-dim)" }, children: "Loading" })] })) }));
|
|
34
36
|
}
|
|
35
37
|
export function TimelinePane({ onInvestigate } = {}) {
|
|
36
38
|
const events = useSelector((s) => {
|
|
39
|
+
let result = s.events;
|
|
37
40
|
const cid = s.filters.correlationId;
|
|
38
|
-
|
|
41
|
+
if (cid)
|
|
42
|
+
result = result.filter((e) => e.correlationId === cid);
|
|
43
|
+
const search = s.filters.search?.toLowerCase();
|
|
44
|
+
if (search) {
|
|
45
|
+
result = result.filter((e) => e.name.toLowerCase().includes(search) ||
|
|
46
|
+
e.payload.toLowerCase().includes(search) ||
|
|
47
|
+
(e.correlationId ?? "").toLowerCase().includes(search));
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
39
50
|
});
|
|
40
51
|
const loading = useSelector((s) => s.loading);
|
|
41
52
|
const hasMore = useSelector((s) => s.hasMore);
|
|
@@ -57,11 +68,8 @@ export function TimelinePane({ onInvestigate } = {}) {
|
|
|
57
68
|
const handleFilterCorrelation = useCallback((correlationId) => {
|
|
58
69
|
dispatch({ type: "ui/filter_changed", payload: { correlationId } });
|
|
59
70
|
}, [dispatch]);
|
|
60
|
-
const handleFilterStream = useCallback((aggregateKey) => {
|
|
61
|
-
dispatch({ type: "ui/filter_changed", payload: { aggregateKey } });
|
|
62
|
-
}, [dispatch]);
|
|
63
71
|
const handleLoadMore = useCallback(() => {
|
|
64
72
|
dispatch({ type: "ui/load_more_requested" });
|
|
65
73
|
}, [dispatch]);
|
|
66
|
-
return (_jsxs("div", { className: "
|
|
74
|
+
return (_jsxs("div", { className: "ci-col", children: [_jsx(FilterBar, {}), loading && events.length === 0 ? (_jsx("div", { className: "ci-pulse", style: { padding: 4 }, children: Array.from({ length: 12 }).map((_, i) => (_jsxs("div", { className: "ci-row", style: { gap: 8, padding: "10px 12px", borderBottom: "1px solid var(--ci-border)" }, children: [_jsx("div", { className: "ci-skeleton", style: { height: 12, width: 40, flexShrink: 0 } }), _jsx("div", { className: "ci-skeleton", style: { height: 12, width: 128, flexShrink: 0 } }), _jsx("div", { className: "ci-skeleton", style: { height: 12, flex: 1, maxWidth: `${150 + (i * 37) % 200}px` } })] }, i))) })) : events.length === 0 ? (_jsx("div", { className: "ci-empty", style: { height: 128, fontSize: 14 }, children: "No events found" })) : (_jsxs("div", { className: "ci-scroll", children: [displayedEvents.map((event) => (_jsx(EventRow, { event: event, isSelected: event.seq === selectedSeq, onClick: () => handleSelect(event), onFilterCorrelation: handleFilterCorrelation, onInvestigate: onInvestigate ? () => onInvestigate(event) : undefined }, event.seq))), hasMore && (_jsx(InfiniteScrollSentinel, { onVisible: handleLoadMore, loading: loading }))] }))] }));
|
|
67
75
|
}
|
|
@@ -27,6 +27,7 @@ const STATUS_COLORS = {
|
|
|
27
27
|
completed: { bar: "#22c55e", barEnd: "#16a34a", text: "#bbf7d0" },
|
|
28
28
|
running: { bar: "#eab308", barEnd: "#ca8a04", text: "#fef08a" },
|
|
29
29
|
error: { bar: "#ef4444", barEnd: "#dc2626", text: "#fecaca" },
|
|
30
|
+
retry: { bar: "#f97316", barEnd: "#ea580c", text: "#fed7aa" },
|
|
30
31
|
};
|
|
31
32
|
function statusColor(status) {
|
|
32
33
|
return STATUS_COLORS[status] ?? STATUS_COLORS.running;
|
|
@@ -57,15 +58,48 @@ function buildBars(outcomes) {
|
|
|
57
58
|
return { bars, minMs, maxMs };
|
|
58
59
|
}
|
|
59
60
|
// ---------------------------------------------------------------------------
|
|
61
|
+
// Attempt helpers
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
/** Group attempts by reactorId, sorted by attempt number. */
|
|
64
|
+
function groupAttempts(attempts) {
|
|
65
|
+
const map = new Map();
|
|
66
|
+
for (const a of attempts) {
|
|
67
|
+
let list = map.get(a.reactorId);
|
|
68
|
+
if (!list) {
|
|
69
|
+
list = [];
|
|
70
|
+
map.set(a.reactorId, list);
|
|
71
|
+
}
|
|
72
|
+
list.push(a);
|
|
73
|
+
}
|
|
74
|
+
for (const list of map.values()) {
|
|
75
|
+
list.sort((a, b) => a.attempt - b.attempt);
|
|
76
|
+
}
|
|
77
|
+
return map;
|
|
78
|
+
}
|
|
79
|
+
/** Factor attempts into the global min/max time range. */
|
|
80
|
+
function expandRange(attempts, minMs, maxMs) {
|
|
81
|
+
for (const a of attempts) {
|
|
82
|
+
const s = new Date(a.startedAt).getTime();
|
|
83
|
+
const e = new Date(a.completedAt).getTime();
|
|
84
|
+
if (s < minMs)
|
|
85
|
+
minMs = s;
|
|
86
|
+
if (e > maxMs)
|
|
87
|
+
maxMs = e;
|
|
88
|
+
}
|
|
89
|
+
return { minMs, maxMs };
|
|
90
|
+
}
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
60
92
|
// Constants
|
|
61
93
|
// ---------------------------------------------------------------------------
|
|
62
94
|
const ROW_HEIGHT = 36;
|
|
95
|
+
const ATTEMPT_ROW_HEIGHT = 26;
|
|
63
96
|
const LABEL_WIDTH = 160;
|
|
64
97
|
const BAR_MIN_WIDTH = 4;
|
|
65
98
|
const PADDING_X = 12;
|
|
66
99
|
export function WaterfallPane() {
|
|
67
100
|
const correlationId = useSelector((s) => s.flowCorrelationId);
|
|
68
101
|
const outcomes = useSelector((s) => correlationId ? s.outcomes[correlationId] ?? [] : []);
|
|
102
|
+
const attempts = useSelector((s) => correlationId ? s.attempts[correlationId] ?? [] : []);
|
|
69
103
|
const flowData = useSelector((s) => s.flowData);
|
|
70
104
|
const scrubberStart = useSelector((s) => s.scrubberStart);
|
|
71
105
|
const scrubberEnd = useSelector((s) => s.scrubberEnd);
|
|
@@ -74,7 +108,17 @@ export function WaterfallPane() {
|
|
|
74
108
|
const handleBarClick = useCallback((bar) => {
|
|
75
109
|
dispatch({ type: "ui/handler_selected", payload: { reactorId: bar.reactorId } });
|
|
76
110
|
}, [dispatch]);
|
|
77
|
-
const
|
|
111
|
+
const attemptsByReactor = useMemo(() => groupAttempts(attempts), [attempts]);
|
|
112
|
+
const { bars, minMs, maxMs } = useMemo(() => {
|
|
113
|
+
const result = buildBars(outcomes);
|
|
114
|
+
// Expand range to include attempt times
|
|
115
|
+
if (attempts.length > 0) {
|
|
116
|
+
const expanded = expandRange(attempts, result.minMs, result.maxMs);
|
|
117
|
+
result.minMs = expanded.minMs;
|
|
118
|
+
result.maxMs = expanded.maxMs;
|
|
119
|
+
}
|
|
120
|
+
return result;
|
|
121
|
+
}, [outcomes, attempts]);
|
|
78
122
|
const rangeMs = maxMs - minMs || 1;
|
|
79
123
|
// Map event id → seq for scrubber sync
|
|
80
124
|
const eventIdToSeq = useMemo(() => {
|
|
@@ -129,78 +173,147 @@ export function WaterfallPane() {
|
|
|
129
173
|
? ((scrubberMs - minMs) / rangeMs) * 100
|
|
130
174
|
: null;
|
|
131
175
|
const isSelected = logsFilter.reactorId === bar.reactorId;
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
flexShrink: 0,
|
|
147
|
-
fontSize: 11,
|
|
148
|
-
color: "#c0c0d0",
|
|
149
|
-
fontWeight: 500,
|
|
150
|
-
overflow: "hidden",
|
|
151
|
-
textOverflow: "ellipsis",
|
|
152
|
-
whiteSpace: "nowrap",
|
|
153
|
-
paddingRight: 10,
|
|
154
|
-
letterSpacing: "0.01em",
|
|
155
|
-
}, title: bar.reactorId, children: bar.reactorId }), _jsxs("div", { style: {
|
|
156
|
-
flex: 1,
|
|
157
|
-
position: "relative",
|
|
158
|
-
height: 22,
|
|
159
|
-
background: "rgba(255, 255, 255, 0.02)",
|
|
160
|
-
borderRadius: 5,
|
|
161
|
-
overflow: "hidden",
|
|
176
|
+
const reactorAttempts = attemptsByReactor.get(bar.reactorId) ?? [];
|
|
177
|
+
const hasMultipleAttempts = reactorAttempts.length > 1;
|
|
178
|
+
return (_jsxs("div", { children: [_jsxs("div", { onClick: () => handleBarClick(bar), style: {
|
|
179
|
+
display: "flex",
|
|
180
|
+
alignItems: "center",
|
|
181
|
+
height: ROW_HEIGHT,
|
|
182
|
+
gap: 0,
|
|
183
|
+
opacity: isFuture ? 0.25 : (hasReactorFilter && !isSelected) ? 0.35 : 1,
|
|
184
|
+
transition: "opacity 200ms, background 150ms",
|
|
185
|
+
cursor: "pointer",
|
|
186
|
+
borderRadius: 6,
|
|
187
|
+
background: isSelected ? "rgba(99, 102, 241, 0.15)" : "transparent",
|
|
188
|
+
paddingLeft: 4,
|
|
189
|
+
paddingRight: 4,
|
|
162
190
|
}, children: [_jsx("div", { style: {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
191
|
+
width: LABEL_WIDTH,
|
|
192
|
+
flexShrink: 0,
|
|
193
|
+
fontSize: 11,
|
|
194
|
+
color: "#c0c0d0",
|
|
195
|
+
fontWeight: 500,
|
|
196
|
+
overflow: "hidden",
|
|
197
|
+
textOverflow: "ellipsis",
|
|
198
|
+
whiteSpace: "nowrap",
|
|
199
|
+
paddingRight: 10,
|
|
200
|
+
letterSpacing: "0.01em",
|
|
201
|
+
}, title: bar.reactorId, children: bar.reactorId }), _jsxs("div", { style: {
|
|
202
|
+
flex: 1,
|
|
203
|
+
position: "relative",
|
|
204
|
+
height: 22,
|
|
205
|
+
background: "rgba(255, 255, 255, 0.02)",
|
|
206
|
+
borderRadius: 5,
|
|
207
|
+
overflow: "hidden",
|
|
208
|
+
}, children: [_jsx("div", { style: {
|
|
209
|
+
position: "absolute",
|
|
210
|
+
left: `${offsetPct}%`,
|
|
211
|
+
width: `${widthPct}%`,
|
|
212
|
+
minWidth: BAR_MIN_WIDTH,
|
|
213
|
+
height: "100%",
|
|
214
|
+
background: `linear-gradient(90deg, ${colors.bar}, ${colors.barEnd})`,
|
|
215
|
+
borderRadius: 4,
|
|
216
|
+
opacity: 0.8,
|
|
217
|
+
display: "flex",
|
|
218
|
+
alignItems: "center",
|
|
219
|
+
paddingLeft: 5,
|
|
220
|
+
paddingRight: 5,
|
|
221
|
+
boxShadow: `0 1px 4px ${colors.bar}30`,
|
|
222
|
+
}, title: `${bar.reactorId}: ${bar.status} (${formatDuration(duration)})${bar.attempts > 1 ? ` — ${bar.attempts} attempts` : ""}${bar.error ? `\nError: ${bar.error}` : ""}`, children: _jsx("span", { style: {
|
|
223
|
+
fontSize: 9,
|
|
224
|
+
fontWeight: 600,
|
|
225
|
+
color: "#0a0a0f",
|
|
226
|
+
whiteSpace: "nowrap",
|
|
227
|
+
overflow: "hidden",
|
|
228
|
+
textOverflow: "ellipsis",
|
|
229
|
+
}, children: formatDuration(duration) }) }), cursorPct != null && (_jsx("div", { style: {
|
|
230
|
+
position: "absolute",
|
|
231
|
+
left: `${cursorPct}%`,
|
|
232
|
+
top: 0,
|
|
233
|
+
bottom: 0,
|
|
234
|
+
width: 1,
|
|
235
|
+
background: "#6366f1",
|
|
236
|
+
pointerEvents: "none",
|
|
237
|
+
boxShadow: "0 0 4px rgba(99, 102, 241, 0.3)",
|
|
238
|
+
} }))] }), _jsxs("div", { style: {
|
|
239
|
+
width: 80,
|
|
240
|
+
flexShrink: 0,
|
|
171
241
|
display: "flex",
|
|
172
242
|
alignItems: "center",
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
243
|
+
gap: 4,
|
|
244
|
+
paddingLeft: 10,
|
|
245
|
+
}, children: [_jsx("span", { style: {
|
|
246
|
+
fontSize: 10,
|
|
247
|
+
fontWeight: 500,
|
|
248
|
+
color: colors.text,
|
|
249
|
+
opacity: 0.8,
|
|
250
|
+
}, children: bar.status }), bar.attempts > 1 && (_jsxs("span", { style: { fontSize: 9, color: "#50506a" }, children: ["x", bar.attempts] }))] })] }), bar.status === "error" && bar.error && (_jsx("div", { style: {
|
|
251
|
+
marginLeft: LABEL_WIDTH + 4,
|
|
252
|
+
marginTop: -2,
|
|
253
|
+
marginBottom: 4,
|
|
254
|
+
fontSize: 10,
|
|
255
|
+
color: "#f87171",
|
|
256
|
+
paddingLeft: 4,
|
|
257
|
+
overflow: "hidden",
|
|
258
|
+
textOverflow: "ellipsis",
|
|
259
|
+
whiteSpace: "nowrap",
|
|
260
|
+
}, title: bar.error, children: bar.error })), hasMultipleAttempts && reactorAttempts.map((att) => {
|
|
261
|
+
const attStartMs = new Date(att.startedAt).getTime();
|
|
262
|
+
const attEndMs = new Date(att.completedAt).getTime();
|
|
263
|
+
const attOffsetPct = ((attStartMs - minMs) / rangeMs) * 100;
|
|
264
|
+
const attWidthPct = Math.max(((attEndMs - attStartMs) / rangeMs) * 100, 0.3);
|
|
265
|
+
const attColors = statusColor(att.status);
|
|
266
|
+
const attDuration = attEndMs - attStartMs;
|
|
267
|
+
return (_jsxs("div", { style: {
|
|
268
|
+
display: "flex",
|
|
269
|
+
alignItems: "center",
|
|
270
|
+
height: ATTEMPT_ROW_HEIGHT,
|
|
271
|
+
opacity: isFuture ? 0.25 : (hasReactorFilter && !isSelected) ? 0.35 : 0.7,
|
|
272
|
+
paddingLeft: 4,
|
|
273
|
+
paddingRight: 4,
|
|
274
|
+
}, children: [_jsxs("div", { style: {
|
|
275
|
+
width: LABEL_WIDTH,
|
|
276
|
+
flexShrink: 0,
|
|
177
277
|
fontSize: 9,
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
whiteSpace: "nowrap",
|
|
278
|
+
color: "#70708a",
|
|
279
|
+
paddingLeft: 16,
|
|
181
280
|
overflow: "hidden",
|
|
182
281
|
textOverflow: "ellipsis",
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
282
|
+
whiteSpace: "nowrap",
|
|
283
|
+
paddingRight: 10,
|
|
284
|
+
}, children: ["attempt ", att.attempt + 1] }), _jsx("div", { style: {
|
|
285
|
+
flex: 1,
|
|
286
|
+
position: "relative",
|
|
287
|
+
height: 14,
|
|
288
|
+
borderRadius: 3,
|
|
289
|
+
}, children: _jsx("div", { style: {
|
|
290
|
+
position: "absolute",
|
|
291
|
+
left: `${attOffsetPct}%`,
|
|
292
|
+
width: `${attWidthPct}%`,
|
|
293
|
+
minWidth: 3,
|
|
294
|
+
height: "100%",
|
|
295
|
+
background: `linear-gradient(90deg, ${attColors.bar}, ${attColors.barEnd})`,
|
|
296
|
+
borderRadius: 3,
|
|
297
|
+
opacity: 0.6,
|
|
298
|
+
display: "flex",
|
|
299
|
+
alignItems: "center",
|
|
300
|
+
paddingLeft: 4,
|
|
301
|
+
paddingRight: 4,
|
|
302
|
+
}, title: `Attempt ${att.attempt + 1}: ${att.status} (${formatDuration(attDuration)})${att.error ? `\n${att.error}` : ""}`, children: _jsx("span", { style: {
|
|
303
|
+
fontSize: 8,
|
|
304
|
+
fontWeight: 600,
|
|
305
|
+
color: "#0a0a0f",
|
|
306
|
+
whiteSpace: "nowrap",
|
|
307
|
+
overflow: "hidden",
|
|
308
|
+
textOverflow: "ellipsis",
|
|
309
|
+
}, children: formatDuration(attDuration) }) }) }), _jsxs("div", { style: {
|
|
310
|
+
width: 80,
|
|
311
|
+
flexShrink: 0,
|
|
312
|
+
paddingLeft: 10,
|
|
313
|
+
fontSize: 9,
|
|
314
|
+
color: attColors.text,
|
|
315
|
+
opacity: 0.6,
|
|
316
|
+
}, children: [att.status, att.error && (_jsx("span", { style: { color: "#70708a", marginLeft: 4 }, title: att.error, children: "!" }))] })] }, `${att.reactorId}-attempt-${att.attempt}`));
|
|
317
|
+
})] }, bar.reactorId));
|
|
205
318
|
}), _jsxs("div", { style: { marginTop: 10, fontSize: 10, color: "#40405a", marginLeft: LABEL_WIDTH, letterSpacing: "0.03em" }, children: ["Total wall time: ", formatDuration(rangeMs)] })] })] }));
|
|
206
319
|
}
|
package/dist/queries.d.ts
CHANGED
|
@@ -13,3 +13,4 @@ export declare const INSPECTOR_AGGREGATE_KEYS = "\n query InspectorAggregateKey
|
|
|
13
13
|
export declare const INSPECTOR_AGGREGATE_LIFECYCLE = "\n query InspectorAggregateLifecycle($aggregateKey: String!, $limit: Int) {\n inspectorAggregateLifecycle(aggregateKey: $aggregateKey, limit: $limit) {\n seq\n eventId\n eventType\n ts\n correlationId\n aggregateKey\n state\n }\n }\n";
|
|
14
14
|
export declare const INSPECTOR_CORRELATIONS = "\n query InspectorCorrelations($search: String, $limit: Int, $cursor: String) {\n inspectorCorrelations(search: $search, limit: $limit, cursor: $cursor) {\n correlations {\n correlationId\n eventCount\n firstTs\n lastTs\n rootEventType\n hasErrors\n }\n nextCursor\n }\n }\n";
|
|
15
15
|
export declare const INSPECTOR_REACTOR_OUTCOMES = "\n query InspectorReactorOutcomes($correlationId: String!) {\n inspectorReactorOutcomes(correlationId: $correlationId) {\n reactorId\n status\n error\n attempts\n startedAt\n completedAt\n triggeringEventIds\n }\n }\n";
|
|
16
|
+
export declare const INSPECTOR_REACTOR_ATTEMPTS = "\n query InspectorReactorAttempts($correlationId: String!) {\n inspectorReactorAttempts(correlationId: $correlationId) {\n eventId\n reactorId\n correlationId\n attempt\n status\n error\n startedAt\n completedAt\n }\n }\n";
|
package/dist/queries.js
CHANGED
|
@@ -172,3 +172,17 @@ export const INSPECTOR_REACTOR_OUTCOMES = `
|
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
174
|
`;
|
|
175
|
+
export const INSPECTOR_REACTOR_ATTEMPTS = `
|
|
176
|
+
query InspectorReactorAttempts($correlationId: String!) {
|
|
177
|
+
inspectorReactorAttempts(correlationId: $correlationId) {
|
|
178
|
+
eventId
|
|
179
|
+
reactorId
|
|
180
|
+
correlationId
|
|
181
|
+
attempt
|
|
182
|
+
status
|
|
183
|
+
error
|
|
184
|
+
startedAt
|
|
185
|
+
completedAt
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
`;
|
package/dist/reducer.js
CHANGED
|
@@ -109,6 +109,11 @@ export const reducer = (draft, event) => {
|
|
|
109
109
|
draft.outcomes[correlationId] = outcomes;
|
|
110
110
|
break;
|
|
111
111
|
}
|
|
112
|
+
case "events/attempts_loaded": {
|
|
113
|
+
const { correlationId, attempts } = event.payload;
|
|
114
|
+
draft.attempts[correlationId] = attempts;
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
112
117
|
case "events/correlations_loaded": {
|
|
113
118
|
const { correlations, hasMore, append } = event.payload;
|
|
114
119
|
if (append) {
|
package/dist/state.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { InspectorEvent, CorrelationSummary, ReactorDependency, AggregateLifecycleEntry, FilterState, FlowSelection, ReactorDescription, ReactorDescriptionSnapshot, AggregateTimelineEntry, ReactorLog, ReactorOutcome, LogsFilter, PaneLayout } from "./types";
|
|
1
|
+
import type { InspectorEvent, CorrelationSummary, ReactorDependency, AggregateLifecycleEntry, FilterState, FlowSelection, ReactorDescription, ReactorDescriptionSnapshot, AggregateTimelineEntry, ReactorLog, ReactorOutcome, ReactorAttempt, LogsFilter, PaneLayout } from "./types";
|
|
2
2
|
export type InspectorState = {
|
|
3
3
|
events: InspectorEvent[];
|
|
4
4
|
hasMore: boolean;
|
|
@@ -22,6 +22,7 @@ export type InspectorState = {
|
|
|
22
22
|
descriptionSnapshots: Record<string, ReactorDescriptionSnapshot[]>;
|
|
23
23
|
aggregateTimeline: Record<string, AggregateTimelineEntry[]>;
|
|
24
24
|
outcomes: Record<string, ReactorOutcome[]>;
|
|
25
|
+
attempts: Record<string, ReactorAttempt[]>;
|
|
25
26
|
correlations: CorrelationSummary[];
|
|
26
27
|
correlationsLoading: boolean;
|
|
27
28
|
correlationsHasMore: boolean;
|
package/dist/state.js
CHANGED
|
@@ -15,6 +15,8 @@ export const initialState = {
|
|
|
15
15
|
search: "",
|
|
16
16
|
correlationId: null,
|
|
17
17
|
aggregateKey: null,
|
|
18
|
+
from: null,
|
|
19
|
+
to: null,
|
|
18
20
|
},
|
|
19
21
|
logs: [],
|
|
20
22
|
logsFilter: {
|
|
@@ -26,6 +28,7 @@ export const initialState = {
|
|
|
26
28
|
descriptionSnapshots: {},
|
|
27
29
|
aggregateTimeline: {},
|
|
28
30
|
outcomes: {},
|
|
31
|
+
attempts: {},
|
|
29
32
|
correlations: [],
|
|
30
33
|
correlationsLoading: false,
|
|
31
34
|
correlationsHasMore: true,
|
package/dist/theme.js
CHANGED
|
@@ -28,7 +28,8 @@ function hslToRgb(h, s, l) {
|
|
|
28
28
|
return [Math.round(f(0) * 255), Math.round(f(8) * 255), Math.round(f(4) * 255)];
|
|
29
29
|
}
|
|
30
30
|
export const LOG_LEVEL_COLORS = {
|
|
31
|
-
debug: "
|
|
32
|
-
info: "
|
|
33
|
-
warn: "
|
|
31
|
+
debug: "ci-log-debug",
|
|
32
|
+
info: "ci-log-info",
|
|
33
|
+
warn: "ci-log-warn",
|
|
34
|
+
error: "ci-log-error",
|
|
34
35
|
};
|
package/dist/types.d.ts
CHANGED
|
@@ -75,6 +75,16 @@ export type ReactorOutcome = {
|
|
|
75
75
|
completedAt: string | null;
|
|
76
76
|
triggeringEventIds: string[];
|
|
77
77
|
};
|
|
78
|
+
export type ReactorAttempt = {
|
|
79
|
+
eventId: string;
|
|
80
|
+
reactorId: string;
|
|
81
|
+
correlationId: string;
|
|
82
|
+
attempt: number;
|
|
83
|
+
status: string;
|
|
84
|
+
error: string | null;
|
|
85
|
+
startedAt: string;
|
|
86
|
+
completedAt: string;
|
|
87
|
+
};
|
|
78
88
|
export type ReactorDescriptionSnapshot = {
|
|
79
89
|
seq: number;
|
|
80
90
|
eventId: string;
|
|
@@ -113,14 +123,12 @@ export type CorrelationSummary = {
|
|
|
113
123
|
rootEventType: string;
|
|
114
124
|
hasErrors: boolean;
|
|
115
125
|
};
|
|
116
|
-
export type CorrelationSummaryPage = {
|
|
117
|
-
correlations: CorrelationSummary[];
|
|
118
|
-
nextCursor: string | null;
|
|
119
|
-
};
|
|
120
126
|
export type FilterState = {
|
|
121
127
|
search: string;
|
|
122
128
|
correlationId: string | null;
|
|
123
129
|
aggregateKey: string | null;
|
|
130
|
+
from: string | null;
|
|
131
|
+
to: string | null;
|
|
124
132
|
};
|
|
125
133
|
export type LogsFilter = {
|
|
126
134
|
scope: "reactor" | "correlation";
|