@workflow/web 5.0.0-beta.26 → 5.0.0-beta.27
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/build/client/assets/{encryption-g14N5vQl.js → encryption-BQTnudEZ.js} +1 -1
- package/build/client/assets/{highlighted-body-B3W2YXNL-QrddlyZu.js → highlighted-body-B3W2YXNL-B-EF8R0t.js} +1 -1
- package/build/client/assets/{home-BNApVOct.js → home-DQkixJk4.js} +3 -3
- package/build/client/assets/{index-B6-SzLmT.js → index-ConSkUmc.js} +0 -2
- package/build/client/assets/{manifest-379f050f.js → manifest-ce6dd06d.js} +1 -1
- package/build/client/assets/{mermaid-3ZIDBTTL-Cg-Mp5Kj.js → mermaid-3ZIDBTTL-aixonSAh.js} +445 -260
- package/build/client/assets/root-BlaSucTH.css +1 -0
- package/build/client/assets/{root-BsPxYsbK.js → root-CsCdj08f.js} +1 -1
- package/build/client/assets/{run-detail-sr7StYc6.js → run-detail-CCsVqid_.js} +975 -760
- package/build/client/assets/server-build-DPrKlhgf.css +1 -0
- package/build/client/assets/{workflow-graph-viewer-CcCwLmnF.js → workflow-graph-viewer-BlPvo_5I.js} +44 -62
- package/build/client/assets/{zstd-browser-decoder-OOeWOMJw.js → zstd-browser-decoder-RyHgsNO3.js} +1 -1
- package/build/server/assets/{app-DQ35jFT1.js → app-kYNGZFkW.js} +1 -1
- package/build/server/assets/{highlighted-body-B3W2YXNL-DUlvgLoF.js → highlighted-body-B3W2YXNL-D1QWoqJB.js} +3 -3
- package/build/server/assets/index-fWQcXKhC.js +115 -0
- package/build/server/assets/{mermaid-3ZIDBTTL-BdnRYE9a.js → mermaid-3ZIDBTTL-BOh-zwwU.js} +3 -3
- package/build/server/assets/{server-build-0CazaFkH.js → server-build-B21fZEey.js} +2114 -1175
- package/build/server/assets/{token-DK_R23fr.js → token-DmIqmbeU.js} +2 -2
- package/build/server/assets/{token-util-CaJAmsYa.js → token-util-D4JYdrFc.js} +2 -2
- package/build/server/assets/{zstd-browser-decoder-pCjqxVHM.js → zstd-browser-decoder-DgO7NCG6.js} +3 -3
- package/build/server/index.js +1 -1
- package/package.json +8 -8
- package/build/client/assets/root-F_dqJDC7.css +0 -1
- package/build/client/assets/server-build-DVBDkRDS.css +0 -1
- package/build/server/assets/index-BgRt1-Z6.js +0 -100
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { r as reactExports, j as jsxRuntimeExports, f as reactDomExports, G as ReactDOM, B as useNavigate, C as useSearchParams, A as Link, w as withComponentProps, H as useParams } from "./index-BXZSIDEp.js";
|
|
2
|
-
import {
|
|
3
|
-
import { c as createLucideIcon,
|
|
4
|
-
import { decrypt, importKey } from "./encryption-
|
|
5
|
-
import "./index-
|
|
2
|
+
import { o as Check, M as Copy, C as CircleAlert, N as parseStepName, y as parseWorkflowName, O as ErrorCard, Q as format, Z as Zap, S as Send, R as ResolveHookModal, n as ChevronUp, X, L as ErrorBoundary, U as Circle, u as unwrapOrThrow, W as WorkflowWebAPIError, G as unwrapServerActionResult, V as useEscapeKeydown, q as composeEventHandlers, Y as useCallbackRef, _ as useLayoutEffect2, p as useControllableState, $ as useId, a0 as createContext2, s as Presence, v as createContextScope, k as hideOthers, l as ReactRemoveScroll, a1 as useFocusGuards, a2 as LAYOUT, a3 as wakeUpRun, r as resumeHook, A as Alert, c as AlertTitle, d as AlertDescription, a as Skeleton$1, a4 as RunActionsButtons, z as StatusBadge, e as CopyableText, b as RelativeTime, T as Tabs, I as TabsList, J as TabsTrigger, K as TabsContent, w as cancelRun, a5 as recreateRun } from "./workflow-graph-viewer-BlPvo_5I.js";
|
|
3
|
+
import { c as createLucideIcon, W as cn, X as DataInspector, Y as DecryptClickContext, Z as Button, $ as Spinner, a0 as Lock, a1 as CollapsibleRoot, a2 as CollapsibleTrigger, a3 as CollapsibleContent, M as cva, a4 as RESERVED_ATTRIBUTE_KEY_PREFIX, a5 as ContextCardProvider, h as useToast, a6 as Skeleton, a7 as Yr, a8 as isEncryptedMarker, C as ChevronRight, a9 as TimestampTooltip, aa as formatDuration, ab as _r, ac as RunClickContext, ad as StreamClickContext, ae as Collapsible, af as isExpiredMarker, ag as isDoStreamStep, ah as extractConversation, ai as hasEncryptedFields, aj as getEventDataRefFields, ak as useSidebarDataOptional, al as clsx, am as useActiveSpan, an as useSidebarData, ao as Tooltip, ap as TooltipTrigger, aq as IconButton, ar as TooltipContent, H as ChevronDown, as as useRowWindow, at as isSpanDimmedBySearch, au as ROW_HEIGHT_PX, av as getSpanDurationMs, aw as formatDurationPrecise, ax as TooltipProvider, ay as ActiveSpanProvider, az as useReducedMotion, aA as searchSpans, aB as computeRootBounds, aC as computeTimeMarkers, aD as getHighResInMs, aE as scrollRowIntoView, aF as TIMELINE_PADDING_PX, aG as Timeline, aH as TimelineHeader, aI as SidebarDataProvider, aJ as fetchHook, l as fetchEvents, aK as hydrateResourceIOAsync, J as fetchRun, aL as fetchStep, aM as hydrateResourceIO, aN as fetchStreams, aO as Slot, I as useComposedRefs, aP as Slottable, e as cn$1, aQ as buttonVariants, aR as fetchEvent, aS as fetchEventsByCorrelationId, aT as isEncryptedData, aU as hydrateData, aV as getWebRevivers, T as Tooltip$1, a as TooltipTrigger$1, b as TooltipContent$1, aW as LIVE_UPDATE_INTERVAL_MS$1, u as useServerConfig, aX as getEncryptionKeyForRun, t as toast, L as LoaderCircle, aY as StreamViewer } from "./mermaid-3ZIDBTTL-aixonSAh.js";
|
|
4
|
+
import { decrypt, importKey } from "./encryption-BQTnudEZ.js";
|
|
5
|
+
import "./index-ConSkUmc.js";
|
|
6
6
|
/**
|
|
7
7
|
* @license lucide-react v0.575.0 - ISC
|
|
8
8
|
*
|
|
@@ -125,166 +125,476 @@ function CopyButton({ copyText, ariaLabel, className }) {
|
|
|
125
125
|
});
|
|
126
126
|
}, children: jsxRuntimeExports.jsxs("div", { className: "relative w-3 h-3", children: [jsxRuntimeExports.jsx("div", { className: cn("absolute inset-0 flex items-center justify-center transition-all duration-150 ease-out", copied ? "scale-100 opacity-100" : "scale-0 opacity-0"), children: jsxRuntimeExports.jsx(Check, { className: "w-3 h-3" }) }), jsxRuntimeExports.jsx("div", { className: cn("absolute inset-0 flex items-center justify-center transition-all duration-150 ease-out", copied ? "scale-0 opacity-0" : "scale-100 opacity-100"), children: jsxRuntimeExports.jsx(Copy, { className: "w-3 h-3" }) })] }) });
|
|
127
127
|
}
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
const serializeForClipboard = (value) => {
|
|
137
|
-
if (typeof value === "string")
|
|
138
|
-
return value;
|
|
139
|
-
if (typeof value === "number" || typeof value === "boolean" || value === null) {
|
|
140
|
-
return String(value);
|
|
141
|
-
}
|
|
142
|
-
try {
|
|
143
|
-
return JSON.stringify(value, null, 2);
|
|
144
|
-
} catch {
|
|
145
|
-
return String(value);
|
|
128
|
+
const ELLIPSIS = "…";
|
|
129
|
+
const MIN_START = 3;
|
|
130
|
+
const MIN_END = 3;
|
|
131
|
+
const MIN_KEPT = MIN_START + MIN_END;
|
|
132
|
+
const graphemeSegmenter = typeof Intl !== "undefined" && "Segmenter" in Intl ? new Intl.Segmenter(void 0, { granularity: "grapheme" }) : null;
|
|
133
|
+
function toGraphemes(text) {
|
|
134
|
+
if (graphemeSegmenter) {
|
|
135
|
+
return [...graphemeSegmenter.segment(text)].map((s) => s.segment);
|
|
146
136
|
}
|
|
147
|
-
|
|
148
|
-
function CopyableDataBlock({ data }) {
|
|
149
|
-
return jsxRuntimeExports.jsxs("div", { className: "relative overflow-x-auto rounded-md border border-gray-alpha-400 p-3", children: [jsxRuntimeExports.jsx(CopyButton, { copyText: serializeForClipboard(data), ariaLabel: "Copy data", className: "absolute right-2 top-2 z-10 flex h-6 w-6 items-center justify-center rounded-md border border-gray-alpha-400 !bg-background-100 p-0 text-gray-900 transition-transform transition-colors duration-100 hover:bg-gray-200 active:scale-95 active:bg-gray-300" }), jsxRuntimeExports.jsx(DataInspector, { data })] });
|
|
137
|
+
return Array.from(text);
|
|
150
138
|
}
|
|
151
|
-
function
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
139
|
+
function buildCandidate(graphemes, kept) {
|
|
140
|
+
if (kept <= 0) {
|
|
141
|
+
return {
|
|
142
|
+
prefixText: "",
|
|
143
|
+
prefixGraphemeCount: 0,
|
|
144
|
+
suffixText: "",
|
|
145
|
+
suffixGraphemeCount: 0,
|
|
146
|
+
text: ELLIPSIS,
|
|
147
|
+
truncated: true
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
const suffixGraphemeCount = kept >= MIN_KEPT ? Math.max(MIN_END, Math.floor(kept / 2)) : Math.floor(kept / 2);
|
|
151
|
+
const prefixGraphemeCount = kept - suffixGraphemeCount;
|
|
152
|
+
const prefixText = graphemes.slice(0, prefixGraphemeCount).join("");
|
|
153
|
+
const suffixText = suffixGraphemeCount > 0 ? graphemes.slice(-suffixGraphemeCount).join("") : "";
|
|
154
|
+
return {
|
|
155
|
+
prefixText,
|
|
156
|
+
prefixGraphemeCount,
|
|
157
|
+
suffixText,
|
|
158
|
+
suffixGraphemeCount,
|
|
159
|
+
text: prefixText + ELLIPSIS + suffixText,
|
|
160
|
+
truncated: true
|
|
159
161
|
};
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
162
|
+
}
|
|
163
|
+
function middleTruncate(graphemes, availableWidth, measure, fullWidth) {
|
|
164
|
+
const fullText = graphemes.join("");
|
|
165
|
+
const resolvedFullWidth = fullWidth ?? measure(fullText);
|
|
166
|
+
if (availableWidth <= 0 || graphemes.length === 0) {
|
|
167
|
+
return {
|
|
168
|
+
prefixText: fullText,
|
|
169
|
+
prefixGraphemeCount: graphemes.length,
|
|
170
|
+
suffixText: "",
|
|
171
|
+
suffixGraphemeCount: 0,
|
|
172
|
+
text: fullText,
|
|
173
|
+
truncated: false
|
|
174
|
+
};
|
|
165
175
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
176
|
+
if (resolvedFullWidth <= availableWidth) {
|
|
177
|
+
return {
|
|
178
|
+
prefixText: fullText,
|
|
179
|
+
prefixGraphemeCount: graphemes.length,
|
|
180
|
+
suffixText: "",
|
|
181
|
+
suffixGraphemeCount: 0,
|
|
182
|
+
text: fullText,
|
|
183
|
+
truncated: false
|
|
184
|
+
};
|
|
169
185
|
}
|
|
170
|
-
|
|
171
|
-
|
|
186
|
+
let lo = 0;
|
|
187
|
+
let hi = graphemes.length - 1;
|
|
188
|
+
let best = -1;
|
|
189
|
+
while (lo <= hi) {
|
|
190
|
+
const mid = lo + hi >>> 1;
|
|
191
|
+
const candidate = buildCandidate(graphemes, mid);
|
|
192
|
+
if (measure(candidate.text) <= availableWidth) {
|
|
193
|
+
best = mid;
|
|
194
|
+
lo = mid + 1;
|
|
195
|
+
} else {
|
|
196
|
+
hi = mid - 1;
|
|
197
|
+
}
|
|
172
198
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const reserved = isReservedAttributeKey(attributeKey);
|
|
185
|
-
return jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-3 py-0.5", children: [jsxRuntimeExports.jsxs("span", { className: "flex min-w-0 items-center gap-1.5 text-label-13 text-gray-900", style: reserved ? { color: "var(--ds-gray-700)" } : void 0, children: [jsxRuntimeExports.jsx("span", { className: "truncate", children: attributeKey }), reserved && jsxRuntimeExports.jsx(ReservedBadge, {})] }), removed ? jsxRuntimeExports.jsx("span", { className: "shrink-0 text-copy-13 italic text-gray-700", children: "removed" }) : jsxRuntimeExports.jsx("span", { className: "max-w-[60%] truncate text-copy-13 text-gray-1000", title: value, children: value })] });
|
|
186
|
-
}
|
|
187
|
-
function sortAttributeKeys(keys) {
|
|
188
|
-
return [...keys].sort((a, b) => {
|
|
189
|
-
const aReserved = isReservedAttributeKey(a);
|
|
190
|
-
const bReserved = isReservedAttributeKey(b);
|
|
191
|
-
if (aReserved !== bReserved)
|
|
192
|
-
return aReserved ? 1 : -1;
|
|
193
|
-
return a.localeCompare(b);
|
|
194
|
-
});
|
|
199
|
+
if (best === -1) {
|
|
200
|
+
return {
|
|
201
|
+
prefixText: "",
|
|
202
|
+
prefixGraphemeCount: 0,
|
|
203
|
+
suffixText: "",
|
|
204
|
+
suffixGraphemeCount: 0,
|
|
205
|
+
text: "",
|
|
206
|
+
truncated: true
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
return buildCandidate(graphemes, best);
|
|
195
210
|
}
|
|
196
|
-
function
|
|
197
|
-
const
|
|
198
|
-
if (
|
|
211
|
+
function getMiddleTruncateCopyText({ prefixText, selectionEnd, selectionStart, suffixText, value }) {
|
|
212
|
+
const visibleText = prefixText + ELLIPSIS + suffixText;
|
|
213
|
+
if (selectionStart < 0 || selectionEnd > visibleText.length || selectionStart >= selectionEnd) {
|
|
199
214
|
return null;
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
}
|
|
208
|
-
function describeWriter(writer) {
|
|
209
|
-
if (!writer)
|
|
215
|
+
}
|
|
216
|
+
if (selectionStart === 0 && selectionEnd === visibleText.length) {
|
|
217
|
+
return value;
|
|
218
|
+
}
|
|
219
|
+
const ellipsisStart = prefixText.length;
|
|
220
|
+
const ellipsisEnd = ellipsisStart + ELLIPSIS.length;
|
|
221
|
+
if (selectionStart > ellipsisStart || selectionEnd < ellipsisEnd) {
|
|
210
222
|
return null;
|
|
211
|
-
if (writer.type === "workflow")
|
|
212
|
-
return "Set by workflow";
|
|
213
|
-
if (writer.type === "step") {
|
|
214
|
-
return `Set by step ${writer.stepId} (attempt ${writer.attempt})`;
|
|
215
223
|
}
|
|
216
|
-
|
|
224
|
+
const originalGraphemes = toGraphemes(value);
|
|
225
|
+
const selectedPrefixGraphemeCount = toGraphemes(visibleText.slice(0, selectionStart)).length;
|
|
226
|
+
const selectedSuffixGraphemeCount = toGraphemes(visibleText.slice(ellipsisEnd, selectionEnd)).length;
|
|
227
|
+
const suffixStart = originalGraphemes.length - toGraphemes(suffixText).length;
|
|
228
|
+
return originalGraphemes.slice(selectedPrefixGraphemeCount, suffixStart + selectedSuffixGraphemeCount).join("");
|
|
217
229
|
}
|
|
218
|
-
function
|
|
219
|
-
|
|
220
|
-
|
|
230
|
+
function getMiddleTruncateCopyTextFromSelectionText({ prefixText, selectionText, suffixText, value }) {
|
|
231
|
+
const visibleText = prefixText + ELLIPSIS + suffixText;
|
|
232
|
+
const trimmedSelectionText = selectionText.trim();
|
|
233
|
+
if (!trimmedSelectionText) {
|
|
234
|
+
return null;
|
|
221
235
|
}
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
const title = message ? deriveTitle(message) : deriveTitle(body);
|
|
244
|
-
const copyText = message && stack && !stack.includes(message) ? `${message}
|
|
245
|
-
|
|
246
|
-
${stack}` : body;
|
|
247
|
-
return jsxRuntimeExports.jsxs("div", { className: "relative overflow-hidden rounded-md border", style: {
|
|
248
|
-
borderColor: "var(--ds-red-400)",
|
|
249
|
-
background: "var(--ds-red-100)"
|
|
250
|
-
}, children: [jsxRuntimeExports.jsx(CopyButton, { copyText, ariaLabel: "Copy error", className: "absolute right-2 top-2 flex h-6 w-6 items-center justify-center rounded-md border border-red-400 bg-red-100 p-0 text-red-900 transition-transform transition-colors duration-100 hover:bg-red-200 active:scale-95" }), title && jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 px-3 py-2.5 pr-10", style: {
|
|
251
|
-
color: "var(--ds-red-900)",
|
|
252
|
-
borderBottom: "1px solid var(--ds-red-400)"
|
|
253
|
-
}, children: [jsxRuntimeExports.jsx(CircleAlert, { className: "h-4 w-4 shrink-0" }), jsxRuntimeExports.jsx("p", {
|
|
254
|
-
className: "text-xs font-semibold m-0 truncate",
|
|
255
|
-
// The full message or stack is in the body below; the header just
|
|
256
|
-
// shows the first line, single-line, with overflow
|
|
257
|
-
// ellipsised so a long title doesn't push the copy button or
|
|
258
|
-
// wrap into the framed hint/docs lines.
|
|
259
|
-
title: message,
|
|
260
|
-
children: title
|
|
261
|
-
})] }), body && jsxRuntimeExports.jsx("pre", { className: "px-3 py-2.5 text-xs font-mono whitespace-pre-wrap break-words overflow-auto m-0", style: {
|
|
262
|
-
color: "var(--ds-red-900)",
|
|
263
|
-
background: "var(--ds-red-200)"
|
|
264
|
-
}, children: body })] });
|
|
236
|
+
const leading = selectionText.slice(0, selectionText.length - selectionText.trimStart().length);
|
|
237
|
+
const trailing = selectionText.slice(selectionText.trimEnd().length);
|
|
238
|
+
if (trimmedSelectionText === visibleText) {
|
|
239
|
+
return leading + value + trailing;
|
|
240
|
+
}
|
|
241
|
+
if (!trimmedSelectionText.includes(ELLIPSIS)) {
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
const selectionStart = visibleText.indexOf(trimmedSelectionText);
|
|
245
|
+
if (selectionStart === -1) {
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
const selectionEnd = selectionStart + trimmedSelectionText.length;
|
|
249
|
+
const mappedText = getMiddleTruncateCopyText({
|
|
250
|
+
prefixText,
|
|
251
|
+
selectionEnd,
|
|
252
|
+
selectionStart,
|
|
253
|
+
suffixText,
|
|
254
|
+
value
|
|
255
|
+
});
|
|
256
|
+
return mappedText === null ? null : leading + mappedText + trailing;
|
|
265
257
|
}
|
|
266
|
-
const
|
|
267
|
-
function
|
|
268
|
-
return
|
|
258
|
+
const useIsomorphicLayoutEffect = typeof window === "undefined" ? reactExports.useEffect : reactExports.useLayoutEffect;
|
|
259
|
+
function createFullState(value, graphemes) {
|
|
260
|
+
return {
|
|
261
|
+
displayText: value,
|
|
262
|
+
isTruncated: false,
|
|
263
|
+
prefixGraphemeCount: graphemes.length,
|
|
264
|
+
prefixText: value,
|
|
265
|
+
suffixGraphemeCount: 0,
|
|
266
|
+
suffixText: ""
|
|
267
|
+
};
|
|
269
268
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
const [open, setOpen] = reactExports.useState(false);
|
|
269
|
+
function useMiddleTruncate(value) {
|
|
270
|
+
const graphemes = reactExports.useMemo(() => toGraphemes(value), [value]);
|
|
271
|
+
const fullState = reactExports.useMemo(() => createFullState(value, graphemes), [graphemes, value]);
|
|
274
272
|
const ref = reactExports.useRef(null);
|
|
275
|
-
const
|
|
276
|
-
reactExports.
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
if (
|
|
281
|
-
|
|
273
|
+
const measureRef = reactExports.useRef(null);
|
|
274
|
+
const [state, setState] = reactExports.useState(() => fullState);
|
|
275
|
+
const rafRef = reactExports.useRef(0);
|
|
276
|
+
const updateState = reactExports.useCallback((nextState) => {
|
|
277
|
+
setState((currentState) => {
|
|
278
|
+
if (currentState.displayText === nextState.displayText && currentState.isTruncated === nextState.isTruncated && currentState.prefixText === nextState.prefixText && currentState.prefixGraphemeCount === nextState.prefixGraphemeCount && currentState.suffixText === nextState.suffixText && currentState.suffixGraphemeCount === nextState.suffixGraphemeCount) {
|
|
279
|
+
return currentState;
|
|
282
280
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
281
|
+
return nextState;
|
|
282
|
+
});
|
|
283
|
+
}, []);
|
|
284
|
+
const recalculate = reactExports.useCallback(() => {
|
|
285
|
+
const el = ref.current;
|
|
286
|
+
const measureEl = measureRef.current;
|
|
287
|
+
if (!el || !measureEl)
|
|
288
|
+
return;
|
|
289
|
+
const available = el.clientWidth;
|
|
290
|
+
if (available <= 0) {
|
|
291
|
+
updateState(fullState);
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
const measure = (text) => {
|
|
295
|
+
measureEl.textContent = text;
|
|
296
|
+
return measureEl.scrollWidth;
|
|
297
|
+
};
|
|
298
|
+
const fullWidth = measure(value);
|
|
299
|
+
if (fullWidth <= available) {
|
|
300
|
+
updateState(fullState);
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
const result = middleTruncate(graphemes, available, measure, fullWidth);
|
|
304
|
+
updateState({
|
|
305
|
+
displayText: result.text,
|
|
306
|
+
isTruncated: result.truncated,
|
|
307
|
+
prefixGraphemeCount: result.prefixGraphemeCount,
|
|
308
|
+
prefixText: result.prefixText,
|
|
309
|
+
suffixGraphemeCount: result.suffixGraphemeCount,
|
|
310
|
+
suffixText: result.suffixText
|
|
311
|
+
});
|
|
312
|
+
}, [fullState, graphemes, updateState, value]);
|
|
313
|
+
useIsomorphicLayoutEffect(() => {
|
|
314
|
+
recalculate();
|
|
315
|
+
}, [recalculate]);
|
|
316
|
+
reactExports.useEffect(() => {
|
|
317
|
+
var _a;
|
|
318
|
+
const el = ref.current;
|
|
319
|
+
if (!el)
|
|
320
|
+
return;
|
|
321
|
+
const debouncedRecalc = () => {
|
|
322
|
+
cancelAnimationFrame(rafRef.current);
|
|
323
|
+
rafRef.current = requestAnimationFrame(recalculate);
|
|
324
|
+
};
|
|
325
|
+
const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(debouncedRecalc) : null;
|
|
326
|
+
ro == null ? void 0 : ro.observe(el);
|
|
327
|
+
window.addEventListener("resize", debouncedRecalc);
|
|
328
|
+
const onFontsLoaded = () => {
|
|
329
|
+
debouncedRecalc();
|
|
330
|
+
};
|
|
331
|
+
const fontSet = "fonts" in document ? document.fonts : null;
|
|
332
|
+
(_a = fontSet == null ? void 0 : fontSet.addEventListener) == null ? void 0 : _a.call(fontSet, "loadingdone", onFontsLoaded);
|
|
333
|
+
return () => {
|
|
334
|
+
var _a2;
|
|
335
|
+
ro == null ? void 0 : ro.disconnect();
|
|
336
|
+
window.removeEventListener("resize", debouncedRecalc);
|
|
337
|
+
cancelAnimationFrame(rafRef.current);
|
|
338
|
+
(_a2 = fontSet == null ? void 0 : fontSet.removeEventListener) == null ? void 0 : _a2.call(fontSet, "loadingdone", onFontsLoaded);
|
|
339
|
+
};
|
|
340
|
+
}, [recalculate]);
|
|
341
|
+
return {
|
|
342
|
+
ref,
|
|
343
|
+
measureRef,
|
|
344
|
+
displayText: state.displayText,
|
|
345
|
+
isTruncated: state.isTruncated,
|
|
346
|
+
prefixGraphemeCount: state.prefixGraphemeCount,
|
|
347
|
+
prefixText: state.prefixText,
|
|
348
|
+
suffixGraphemeCount: state.suffixGraphemeCount,
|
|
349
|
+
suffixText: state.suffixText
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
function getRangeOffsets(container, range) {
|
|
353
|
+
if (!container.contains(range.startContainer) || !container.contains(range.endContainer)) {
|
|
354
|
+
return null;
|
|
355
|
+
}
|
|
356
|
+
const startRange = document.createRange();
|
|
357
|
+
startRange.selectNodeContents(container);
|
|
358
|
+
startRange.setEnd(range.startContainer, range.startOffset);
|
|
359
|
+
const endRange = document.createRange();
|
|
360
|
+
endRange.selectNodeContents(container);
|
|
361
|
+
endRange.setEnd(range.endContainer, range.endOffset);
|
|
362
|
+
return {
|
|
363
|
+
end: endRange.toString().length,
|
|
364
|
+
start: startRange.toString().length
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
function MiddleTruncate({ value, className, onCopy: onCopyProp, ...props }) {
|
|
368
|
+
const { ref, measureRef, displayText, isTruncated, prefixText, suffixText } = useMiddleTruncate(value);
|
|
369
|
+
const visibleRef = reactExports.useRef(null);
|
|
370
|
+
const handleCopy = reactExports.useCallback((e) => {
|
|
371
|
+
onCopyProp == null ? void 0 : onCopyProp(e);
|
|
372
|
+
if (e.defaultPrevented || !isTruncated)
|
|
373
|
+
return;
|
|
374
|
+
const selection = window.getSelection();
|
|
375
|
+
if (!selection || selection.rangeCount === 0)
|
|
376
|
+
return;
|
|
377
|
+
const selectionText = selection.toString();
|
|
378
|
+
if (!selectionText)
|
|
379
|
+
return;
|
|
380
|
+
const range = selection.getRangeAt(0);
|
|
381
|
+
const visibleEl = visibleRef.current;
|
|
382
|
+
let copyText = null;
|
|
383
|
+
if (e.currentTarget.contains(range.startContainer) && e.currentTarget.contains(range.endContainer) && visibleEl) {
|
|
384
|
+
const offsets = getRangeOffsets(visibleEl, range);
|
|
385
|
+
if (offsets) {
|
|
386
|
+
copyText = getMiddleTruncateCopyText({
|
|
387
|
+
prefixText,
|
|
388
|
+
selectionEnd: offsets.end,
|
|
389
|
+
selectionStart: offsets.start,
|
|
390
|
+
suffixText,
|
|
391
|
+
value
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
copyText ?? (copyText = getMiddleTruncateCopyTextFromSelectionText({
|
|
396
|
+
prefixText,
|
|
397
|
+
selectionText,
|
|
398
|
+
suffixText,
|
|
399
|
+
value
|
|
400
|
+
}));
|
|
401
|
+
if (copyText === null)
|
|
402
|
+
return;
|
|
403
|
+
e.preventDefault();
|
|
404
|
+
e.clipboardData.setData("text/plain", copyText);
|
|
405
|
+
}, [onCopyProp, isTruncated, prefixText, suffixText, value]);
|
|
406
|
+
return jsxRuntimeExports.jsxs("span", { title: isTruncated ? value : void 0, ...props, ref, className: cn("relative inline-grid min-w-0 max-w-full overflow-hidden whitespace-nowrap", className), onCopy: handleCopy, children: [isTruncated && jsxRuntimeExports.jsx("span", { className: "sr-only select-none", children: value }), jsxRuntimeExports.jsx("span", { "aria-hidden": "true", className: "pointer-events-none col-start-1 row-start-1 invisible select-none whitespace-nowrap", children: value }), jsxRuntimeExports.jsx("span", { "aria-hidden": isTruncated || void 0, className: "col-start-1 row-start-1 min-w-0 overflow-hidden", ref: visibleRef, children: isTruncated ? jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("span", { children: prefixText }), jsxRuntimeExports.jsx("span", { children: ELLIPSIS }), jsxRuntimeExports.jsx("span", { children: suffixText })] }) : displayText }), jsxRuntimeExports.jsx("span", { "aria-hidden": "true", className: "pointer-events-none absolute left-0 top-0 inline-block invisible select-none whitespace-nowrap", ref: measureRef })] });
|
|
407
|
+
}
|
|
408
|
+
const encryptedPlaceholderPreview = `{
|
|
409
|
+
"input": "[encrypted]",
|
|
410
|
+
"result": "[encrypted]"
|
|
411
|
+
}`;
|
|
412
|
+
function EncryptedDataBlock() {
|
|
413
|
+
const ctx = reactExports.useContext(DecryptClickContext);
|
|
414
|
+
return jsxRuntimeExports.jsxs("div", { className: "relative min-h-20 overflow-hidden rounded-md border border-gray-alpha-400 bg-background-100", children: [jsxRuntimeExports.jsx("pre", { "aria-hidden": "true", className: "pointer-events-none m-0 select-none p-3 font-mono text-label-12 text-gray-900 blur-[4px]", children: encryptedPlaceholderPreview }), jsxRuntimeExports.jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: ctx ? jsxRuntimeExports.jsxs(Button, { onClick: ctx.onDecrypt, disabled: ctx.isDecrypting, size: "xs", children: [ctx.isDecrypting ? jsxRuntimeExports.jsx(Spinner, { size: 10 }) : jsxRuntimeExports.jsx(Lock, { className: "h-3 w-3" }), jsxRuntimeExports.jsx("span", { children: "Decrypt" })] }) : jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1 rounded border border-gray-alpha-400 bg-gray-100 px-1.5 py-0.5 text-button-12 font-medium text-gray-700", children: [jsxRuntimeExports.jsx(Lock, { className: "h-3 w-3" }), "Encrypted"] }) })] });
|
|
415
|
+
}
|
|
416
|
+
const serializeForClipboard = (value) => {
|
|
417
|
+
if (typeof value === "string")
|
|
418
|
+
return value;
|
|
419
|
+
if (typeof value === "number" || typeof value === "boolean" || value === null) {
|
|
420
|
+
return String(value);
|
|
421
|
+
}
|
|
422
|
+
try {
|
|
423
|
+
return JSON.stringify(value, null, 2);
|
|
424
|
+
} catch {
|
|
425
|
+
return String(value);
|
|
426
|
+
}
|
|
427
|
+
};
|
|
428
|
+
function CopyableDataBlock({ data }) {
|
|
429
|
+
return jsxRuntimeExports.jsxs("div", { className: "relative overflow-x-auto rounded-md border border-gray-alpha-400 p-3", children: [jsxRuntimeExports.jsx(CopyButton, { copyText: serializeForClipboard(data), ariaLabel: "Copy data", className: "absolute right-2 top-2 z-10 flex h-6 w-6 items-center justify-center rounded-md border border-gray-alpha-400 !bg-background-100 p-0 text-gray-900 transition-transform transition-colors duration-100 hover:bg-gray-200 active:scale-95 active:bg-gray-300" }), jsxRuntimeExports.jsx(DataInspector, { data })] });
|
|
430
|
+
}
|
|
431
|
+
function isReservedAttributeKey(key) {
|
|
432
|
+
return key.startsWith(RESERVED_ATTRIBUTE_KEY_PREFIX);
|
|
433
|
+
}
|
|
434
|
+
const rowValueVariants = cva("max-w-[60%] truncate text-right text-copy-13 text-gray-1000", {
|
|
435
|
+
variants: {
|
|
436
|
+
variant: {
|
|
437
|
+
default: "",
|
|
438
|
+
mono: "font-mono"
|
|
439
|
+
}
|
|
440
|
+
},
|
|
441
|
+
defaultVariants: {
|
|
442
|
+
variant: "default"
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
const rowCopyValueVariants = cva("flex min-w-0 max-w-[60%] items-center justify-end gap-1 text-copy-13 text-gray-1000", {
|
|
446
|
+
variants: {
|
|
447
|
+
variant: {
|
|
448
|
+
default: "",
|
|
449
|
+
mono: "font-mono"
|
|
450
|
+
}
|
|
451
|
+
},
|
|
452
|
+
defaultVariants: {
|
|
453
|
+
variant: "default"
|
|
454
|
+
}
|
|
455
|
+
});
|
|
456
|
+
function DetailKeyValueRowBase({ label, value, copyText, removed = false, variant }) {
|
|
457
|
+
const stringValue = typeof value === "string" ? value : void 0;
|
|
458
|
+
return jsxRuntimeExports.jsxs("div", { className: "px-1.5 hover:bg-gray-100 flex justify-between gap-3 -mx-1.5 py-0.5 rounded items-center", children: [jsxRuntimeExports.jsx("span", { className: "flex min-w-0 items-center gap-1.5 truncate text-label-13 text-gray-900", children: label }), removed ? jsxRuntimeExports.jsx("span", { className: "shrink-0 text-copy-13 italic text-gray-700", children: "removed" }) : copyText ? jsxRuntimeExports.jsxs("div", { className: cn(rowCopyValueVariants({ variant })), title: copyText, children: [jsxRuntimeExports.jsx(MiddleTruncate, { value: copyText, className: cn(rowValueVariants({ variant, className: "text-right" })), style: { gridTemplateColumns: "minmax(0, 1fr)" } }), jsxRuntimeExports.jsx(CopyButton, { copyText, ariaLabel: `Copy ${label}`, className: "shrink-0 -mr-1" })] }) : jsxRuntimeExports.jsx("span", { className: cn(rowValueVariants({ variant })), title: stringValue, children: value })] });
|
|
459
|
+
}
|
|
460
|
+
function DetailKeyValueRow(props) {
|
|
461
|
+
return jsxRuntimeExports.jsx(DetailKeyValueRowBase, { ...props });
|
|
462
|
+
}
|
|
463
|
+
function DetailMonoKeyValueRow(props) {
|
|
464
|
+
return jsxRuntimeExports.jsx(DetailKeyValueRowBase, { ...props, variant: "mono" });
|
|
465
|
+
}
|
|
466
|
+
function AttributeRow({ attributeKey, value, removed = false }) {
|
|
467
|
+
return jsxRuntimeExports.jsx(DetailKeyValueRow, { label: attributeKey, value, removed });
|
|
468
|
+
}
|
|
469
|
+
function sortAttributeKeys(keys) {
|
|
470
|
+
return [...keys].sort((a, b) => {
|
|
471
|
+
const aReserved = isReservedAttributeKey(a);
|
|
472
|
+
const bReserved = isReservedAttributeKey(b);
|
|
473
|
+
if (aReserved !== bReserved)
|
|
474
|
+
return aReserved ? 1 : -1;
|
|
475
|
+
return a.localeCompare(b);
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
function RunAttributesCard({ attributes }) {
|
|
479
|
+
const keys = sortAttributeKeys(Object.keys(attributes));
|
|
480
|
+
if (keys.length === 0)
|
|
481
|
+
return null;
|
|
482
|
+
return jsxRuntimeExports.jsxs(CollapsibleRoot, { defaultOpen: true, children: [jsxRuntimeExports.jsx(CollapsibleTrigger, { children: "Attributes" }), jsxRuntimeExports.jsx(CollapsibleContent, { className: "mb-4", children: jsxRuntimeExports.jsx("div", { className: "flex flex-col", children: keys.map((key) => jsxRuntimeExports.jsx(AttributeRow, { attributeKey: key, value: attributes[key] }, key)) }) })] });
|
|
483
|
+
}
|
|
484
|
+
function formatMetadataValue(value) {
|
|
485
|
+
if (value == null) {
|
|
486
|
+
return String(value);
|
|
487
|
+
}
|
|
488
|
+
if (typeof value === "string") {
|
|
489
|
+
return value;
|
|
490
|
+
}
|
|
491
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
492
|
+
return String(value);
|
|
493
|
+
}
|
|
494
|
+
try {
|
|
495
|
+
return JSON.stringify(value);
|
|
496
|
+
} catch {
|
|
497
|
+
return String(value);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
function isMetadataRecord(value) {
|
|
501
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
502
|
+
}
|
|
503
|
+
function RunMetadataCard({ metadata }) {
|
|
504
|
+
if (!isMetadataRecord(metadata)) {
|
|
505
|
+
return jsxRuntimeExports.jsxs(CollapsibleRoot, { defaultOpen: true, children: [jsxRuntimeExports.jsx(CollapsibleTrigger, { children: "Metadata" }), jsxRuntimeExports.jsx(CollapsibleContent, { className: "mb-4", children: jsxRuntimeExports.jsx(CopyableDataBlock, { data: metadata }) })] });
|
|
506
|
+
}
|
|
507
|
+
const keys = Object.keys(metadata).sort((a, b) => a.localeCompare(b));
|
|
508
|
+
if (keys.length === 0)
|
|
509
|
+
return null;
|
|
510
|
+
return jsxRuntimeExports.jsxs(CollapsibleRoot, { defaultOpen: true, children: [jsxRuntimeExports.jsx(CollapsibleTrigger, { children: "Metadata" }), jsxRuntimeExports.jsx(CollapsibleContent, { className: "mb-4", children: jsxRuntimeExports.jsx("div", { className: "flex flex-col", children: keys.map((key) => jsxRuntimeExports.jsx(AttributeRow, { attributeKey: key, value: formatMetadataValue(metadata[key]) }, key)) }) })] });
|
|
511
|
+
}
|
|
512
|
+
function isAttrSetEventData(data) {
|
|
513
|
+
if (data === null || typeof data !== "object")
|
|
514
|
+
return false;
|
|
515
|
+
const record = data;
|
|
516
|
+
return Array.isArray(record.changes) && record.changes.every((c) => c !== null && typeof c === "object" && typeof c.key === "string");
|
|
517
|
+
}
|
|
518
|
+
function describeWriter(writer) {
|
|
519
|
+
if (!writer)
|
|
520
|
+
return null;
|
|
521
|
+
if (writer.type === "workflow")
|
|
522
|
+
return "Set by workflow";
|
|
523
|
+
if (writer.type === "step") {
|
|
524
|
+
return `Set by step ${writer.stepId} (attempt ${writer.attempt})`;
|
|
525
|
+
}
|
|
526
|
+
return null;
|
|
527
|
+
}
|
|
528
|
+
function AttrSetEventBlock({ data }) {
|
|
529
|
+
if (!isAttrSetEventData(data)) {
|
|
530
|
+
return jsxRuntimeExports.jsx(CopyableDataBlock, { data });
|
|
531
|
+
}
|
|
532
|
+
const writerLabel = describeWriter(data.writer);
|
|
533
|
+
return jsxRuntimeExports.jsxs("div", { className: "flex flex-col px-3 py-1", children: [jsxRuntimeExports.jsx("div", { className: "flex flex-col", children: data.changes.map((change, index) => jsxRuntimeExports.jsx(AttributeRow, { attributeKey: change.key, removed: change.value === null, value: change.value ?? void 0 }, `${change.key}:${index}`)) }), writerLabel && jsxRuntimeExports.jsx("div", { className: "border-t py-1.5 text-label-12", style: {
|
|
534
|
+
borderColor: "var(--ds-gray-alpha-400)",
|
|
535
|
+
color: "var(--ds-gray-700)"
|
|
536
|
+
}, children: writerLabel })] });
|
|
537
|
+
}
|
|
538
|
+
const STYLES$2 = `.wf-decrypt-btn{appearance:none;-webkit-appearance:none;border:none;display:inline-flex;align-items:center;justify-content:center;height:40px;padding:0 12px;border-radius:6px;font-size:14px;font-weight:500;line-height:20px;cursor:pointer;white-space:nowrap;gap:6px;transition:background 150ms}.wf-decrypt-idle{color:var(--ds-gray-1000);background:var(--ds-background-100);box-shadow:0 0 0 1px var(--ds-gray-400)}.wf-decrypt-idle:hover{background:var(--ds-gray-alpha-200)}.wf-decrypt-done{color:var(--ds-green-900);background:var(--ds-green-100);box-shadow:0 0 0 1px var(--ds-green-400);cursor:default}`;
|
|
539
|
+
function DecryptButton({ decrypted = false, loading = false, onClick }) {
|
|
540
|
+
return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("style", { dangerouslySetInnerHTML: { __html: STYLES$2 } }), jsxRuntimeExports.jsxs("button", { type: "button", onClick: decrypted ? void 0 : onClick, disabled: decrypted || loading, className: `wf-decrypt-btn ${decrypted ? "wf-decrypt-done" : "wf-decrypt-idle"}`, children: [loading ? jsxRuntimeExports.jsx(Spinner, { size: 14 }) : decrypted ? jsxRuntimeExports.jsxs("svg", { width: 14, height: 14, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }), jsxRuntimeExports.jsx("path", { d: "M7 11V7a5 5 0 0 1 9.9-1" })] }) : jsxRuntimeExports.jsxs("svg", { width: 14, height: 14, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }), jsxRuntimeExports.jsx("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })] }), loading ? "Decrypting…" : decrypted ? "Decrypted" : "Decrypt"] })] });
|
|
541
|
+
}
|
|
542
|
+
function isStructuredError(value) {
|
|
543
|
+
return value != null && typeof value === "object" && (typeof value.message === "string" || typeof value.stack === "string");
|
|
544
|
+
}
|
|
545
|
+
function deriveTitle(message) {
|
|
546
|
+
const firstLine = message.split("\n").find((line) => line.trim().length > 0) ?? message;
|
|
547
|
+
return firstLine.trim();
|
|
548
|
+
}
|
|
549
|
+
function ErrorStackBlock({ value }) {
|
|
550
|
+
const stack = typeof value.stack === "string" ? value.stack : void 0;
|
|
551
|
+
const message = typeof value.message === "string" ? value.message : void 0;
|
|
552
|
+
const body = stack ?? message ?? "";
|
|
553
|
+
const title = message ? deriveTitle(message) : deriveTitle(body);
|
|
554
|
+
const copyText = message && stack && !stack.includes(message) ? `${message}
|
|
555
|
+
|
|
556
|
+
${stack}` : body;
|
|
557
|
+
return jsxRuntimeExports.jsxs("div", { className: "relative overflow-hidden rounded-md border", style: {
|
|
558
|
+
borderColor: "var(--ds-red-400)",
|
|
559
|
+
background: "var(--ds-red-100)"
|
|
560
|
+
}, children: [jsxRuntimeExports.jsx(CopyButton, { copyText, ariaLabel: "Copy error", className: "absolute right-2 top-2 flex h-6 w-6 items-center justify-center rounded-md border border-red-400 bg-red-100 p-0 text-red-900 transition-transform transition-colors duration-100 hover:bg-red-200 active:scale-95" }), title && jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 px-3 py-2.5 pr-10", style: {
|
|
561
|
+
color: "var(--ds-red-900)",
|
|
562
|
+
borderBottom: "1px solid var(--ds-red-400)"
|
|
563
|
+
}, children: [jsxRuntimeExports.jsx(CircleAlert, { className: "h-4 w-4 shrink-0" }), jsxRuntimeExports.jsx("p", {
|
|
564
|
+
className: "text-xs font-semibold m-0 truncate",
|
|
565
|
+
// The full message or stack is in the body below; the header just
|
|
566
|
+
// shows the first line, single-line, with overflow
|
|
567
|
+
// ellipsised so a long title doesn't push the copy button or
|
|
568
|
+
// wrap into the framed hint/docs lines.
|
|
569
|
+
title: message,
|
|
570
|
+
children: title
|
|
571
|
+
})] }), body && jsxRuntimeExports.jsx("pre", { className: "px-3 py-2.5 text-xs font-mono whitespace-pre-wrap break-words overflow-auto m-0", style: {
|
|
572
|
+
color: "var(--ds-red-900)",
|
|
573
|
+
background: "var(--ds-red-200)"
|
|
574
|
+
}, children: body })] });
|
|
575
|
+
}
|
|
576
|
+
const STYLES$1 = `.wf-load-more{appearance:none;-webkit-appearance:none;border:none;display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;border-radius:6px;font-size:13px;font-weight:500;line-height:20px;color:var(--ds-gray-1000);background:var(--ds-background-100);box-shadow:0 0 0 1px var(--ds-gray-400);cursor:pointer;white-space:nowrap;gap:6px;transition:background 150ms}.wf-load-more:hover{background:var(--ds-gray-alpha-200)}.wf-load-more:disabled{opacity:.6;cursor:default}.wf-load-more:disabled:hover{background:var(--ds-background-100)}`;
|
|
577
|
+
function LoadMoreButton({ loading = false, onClick, label = "Load more", loadingLabel = "Loading..." }) {
|
|
578
|
+
return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("style", { dangerouslySetInnerHTML: { __html: STYLES$1 } }), jsxRuntimeExports.jsxs("button", { type: "button", onClick, disabled: loading, className: "wf-load-more", children: [loading && jsxRuntimeExports.jsx(Spinner, { size: 14 }), loading ? loadingLabel : label] })] });
|
|
579
|
+
}
|
|
580
|
+
const STYLES = `.wf-menu-btn{appearance:none;-webkit-appearance:none;border:none;display:inline-flex;align-items:center;justify-content:center;height:40px;padding:0 12px;border-radius:6px;font-size:14px;font-weight:500;line-height:20px;color:var(--ds-gray-1000);background:var(--ds-background-100);box-shadow:0 0 0 1px var(--ds-gray-400);cursor:pointer;white-space:nowrap;transition:background 150ms}.wf-menu-btn:hover{background:var(--ds-gray-alpha-200)}.wf-menu-item{appearance:none;-webkit-appearance:none;border:none;display:flex;align-items:center;width:100%;height:40px;padding:0 8px;border-radius:6px;font-size:14px;color:var(--ds-gray-1000);background:transparent;cursor:pointer;transition:background 150ms}.wf-menu-item:hover{background:var(--ds-gray-alpha-100)}`;
|
|
581
|
+
function MenuDropdown({ options, value, onChange }) {
|
|
582
|
+
var _a, _b;
|
|
583
|
+
const [open, setOpen] = reactExports.useState(false);
|
|
584
|
+
const ref = reactExports.useRef(null);
|
|
585
|
+
const label = ((_a = options.find((o) => o.value === value)) == null ? void 0 : _a.label) ?? ((_b = options[0]) == null ? void 0 : _b.label) ?? "";
|
|
586
|
+
reactExports.useEffect(() => {
|
|
587
|
+
if (!open)
|
|
588
|
+
return;
|
|
589
|
+
function handleClickOutside(e) {
|
|
590
|
+
if (ref.current && !ref.current.contains(e.target)) {
|
|
591
|
+
setOpen(false);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
595
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
596
|
+
}, [open]);
|
|
597
|
+
return jsxRuntimeExports.jsxs("div", { ref, style: { position: "relative", flexShrink: 0 }, children: [jsxRuntimeExports.jsx("style", { dangerouslySetInnerHTML: { __html: STYLES } }), jsxRuntimeExports.jsxs("button", { type: "button", className: "wf-menu-btn", onClick: () => setOpen(!open), children: [jsxRuntimeExports.jsx("span", { children: label }), jsxRuntimeExports.jsx("svg", { width: 16, height: 16, viewBox: "0 0 16 16", fill: "none", style: {
|
|
288
598
|
marginLeft: 16,
|
|
289
599
|
marginRight: -4,
|
|
290
600
|
color: "var(--ds-gray-900)"
|
|
@@ -1040,7 +1350,13 @@ function EventListViewInner({ events, run, onLoadEventData, hasMoreEvents = fals
|
|
|
1040
1350
|
function EventListView(props) {
|
|
1041
1351
|
return jsxRuntimeExports.jsx(ContextCardProvider, { children: jsxRuntimeExports.jsx(EventListViewInner, { ...props }) });
|
|
1042
1352
|
}
|
|
1043
|
-
const
|
|
1353
|
+
const GUTTER_PX = 1;
|
|
1354
|
+
const MIN_PX = 50;
|
|
1355
|
+
const DEFAULT_START_PX = 340;
|
|
1356
|
+
function paneColTemplate(startPx) {
|
|
1357
|
+
return `${startPx}px ${GUTTER_PX}px minmax(${MIN_PX}px, 1fr)`;
|
|
1358
|
+
}
|
|
1359
|
+
const COL_TEMPLATE = paneColTemplate(DEFAULT_START_PX);
|
|
1044
1360
|
const ROWS = [
|
|
1045
1361
|
{ id: "r0", name: 62, off: 0, bar: 72 },
|
|
1046
1362
|
{ id: "r1", name: 78, off: 6, bar: 48 },
|
|
@@ -1235,124 +1551,36 @@ const stepEventsToStepEntity = (events) => {
|
|
|
1235
1551
|
};
|
|
1236
1552
|
function stepToSpan(stepEvents, maxEndTime) {
|
|
1237
1553
|
const step = stepEventsToStepEntity(stepEvents);
|
|
1238
|
-
if (!step) {
|
|
1239
|
-
return null;
|
|
1240
|
-
}
|
|
1241
|
-
const parsedName = parseStepName(String(step.stepName));
|
|
1242
|
-
const attributes = {
|
|
1243
|
-
resource: "step",
|
|
1244
|
-
data: step
|
|
1245
|
-
};
|
|
1246
|
-
const resource = "step";
|
|
1247
|
-
const events = convertEventsToSpanEvents(stepEvents, false, {
|
|
1248
|
-
preferOccurredAt: true
|
|
1249
|
-
});
|
|
1250
|
-
const spanStartEvent = stepEvents.find((event) => event.eventType === "step_created") ?? stepEvents[0];
|
|
1251
|
-
const spanStartTime = getEventTimestamp(spanStartEvent) ?? new Date(step.createdAt);
|
|
1252
|
-
let activeStartTime = step.startedAt ? new Date(step.startedAt) : void 0;
|
|
1253
|
-
const firstStartEvent = stepEvents.find((event) => event.eventType === "step_started");
|
|
1254
|
-
if (firstStartEvent) {
|
|
1255
|
-
activeStartTime = getEventTimestamp(firstStartEvent) ?? new Date(firstStartEvent.createdAt);
|
|
1256
|
-
}
|
|
1257
|
-
let endTime = new Date(maxEndTime);
|
|
1258
|
-
if (step.completedAt) {
|
|
1259
|
-
const completedEvent = stepEvents.slice().reverse().find((event) => event.eventType === "step_completed" || event.eventType === "step_failed");
|
|
1260
|
-
endTime = getEventTimestamp(completedEvent) ?? new Date(step.completedAt);
|
|
1261
|
-
}
|
|
1262
|
-
return {
|
|
1263
|
-
spanId: String(step.stepId),
|
|
1264
|
-
name: (parsedName == null ? void 0 : parsedName.shortName) ?? String(step.stepName),
|
|
1265
|
-
kind: 1,
|
|
1266
|
-
// INTERNAL span kind
|
|
1267
|
-
resource,
|
|
1268
|
-
library: WORKFLOW_LIBRARY,
|
|
1269
|
-
status: { code: 0 },
|
|
1270
|
-
traceFlags: 1,
|
|
1271
|
-
attributes,
|
|
1272
|
-
links: [],
|
|
1273
|
-
events,
|
|
1274
|
-
startTime: dateToOtelTime(spanStartTime),
|
|
1275
|
-
endTime: dateToOtelTime(endTime),
|
|
1276
|
-
duration: calculateDuration(spanStartTime, endTime),
|
|
1277
|
-
// Only set activeStartTime if it differs from startTime (i.e., there was a queued period)
|
|
1278
|
-
activeStartTime: activeStartTime && activeStartTime.getTime() > spanStartTime.getTime() ? dateToOtelTime(activeStartTime) : void 0
|
|
1279
|
-
};
|
|
1280
|
-
}
|
|
1281
|
-
const hookEventsToHookEntity = (events) => {
|
|
1282
|
-
var _a;
|
|
1283
|
-
const createdEvent = events.find((event) => event.eventType === "hook_created");
|
|
1284
|
-
if (!createdEvent) {
|
|
1285
|
-
return null;
|
|
1286
|
-
}
|
|
1287
|
-
const receivedEvents = events.filter((event) => event.eventType === "hook_received");
|
|
1288
|
-
const disposedEvents = events.filter((event) => event.eventType === "hook_disposed");
|
|
1289
|
-
const lastReceivedEvent = receivedEvents.at(-1);
|
|
1290
|
-
return {
|
|
1291
|
-
hookId: createdEvent.correlationId,
|
|
1292
|
-
runId: createdEvent.runId,
|
|
1293
|
-
token: (_a = createdEvent.eventData) == null ? void 0 : _a.token,
|
|
1294
|
-
createdAt: getEventTimestamp(createdEvent) ?? createdEvent.createdAt,
|
|
1295
|
-
receivedCount: receivedEvents.length,
|
|
1296
|
-
lastReceivedAt: getEventTimestamp(lastReceivedEvent),
|
|
1297
|
-
disposedAt: getEventTimestamp(disposedEvents.at(-1))
|
|
1298
|
-
};
|
|
1299
|
-
};
|
|
1300
|
-
function hookToSpan(hookEvents, maxEndTime) {
|
|
1301
|
-
const hook = hookEventsToHookEntity(hookEvents);
|
|
1302
|
-
if (!hook) {
|
|
1303
|
-
return null;
|
|
1304
|
-
}
|
|
1305
|
-
const events = convertEventsToSpanEvents(hookEvents, false);
|
|
1306
|
-
const endTime = hook.disposedAt || maxEndTime;
|
|
1307
|
-
return {
|
|
1308
|
-
spanId: String(hook.hookId),
|
|
1309
|
-
name: hook.token ?? String(hook.hookId),
|
|
1310
|
-
kind: 1,
|
|
1311
|
-
// INTERNAL span kind
|
|
1312
|
-
resource: "hook",
|
|
1313
|
-
library: WORKFLOW_LIBRARY,
|
|
1314
|
-
status: { code: 1 },
|
|
1315
|
-
traceFlags: 1,
|
|
1316
|
-
attributes: {
|
|
1317
|
-
resource: "hook",
|
|
1318
|
-
data: hook
|
|
1319
|
-
},
|
|
1320
|
-
links: [],
|
|
1321
|
-
events,
|
|
1322
|
-
startTime: dateToOtelTime(hook.createdAt),
|
|
1323
|
-
endTime: dateToOtelTime(endTime),
|
|
1324
|
-
duration: calculateDuration(hook.createdAt, endTime)
|
|
1325
|
-
};
|
|
1326
|
-
}
|
|
1327
|
-
function runToSpan(run, runEvents, nowTime) {
|
|
1328
|
-
var _a;
|
|
1329
|
-
const now = nowTime ?? /* @__PURE__ */ new Date();
|
|
1330
|
-
const runCreatedEvent = runEvents.find((event) => event.eventType === "run_created");
|
|
1331
|
-
const runStartedEvent = runEvents.find((event) => event.eventType === "run_started");
|
|
1332
|
-
const terminalEvent = runEvents.slice().reverse().find((event) => event.eventType === "run_completed" || event.eventType === "run_failed" || event.eventType === "run_cancelled");
|
|
1333
|
-
const spanStartTime = getEventTimestamp(runCreatedEvent) ?? new Date(run.createdAt);
|
|
1334
|
-
const activeStartTime = getEventTimestamp(runStartedEvent) ?? (run.startedAt ? new Date(run.startedAt) : void 0);
|
|
1335
|
-
const completedAt = getEventTimestamp(terminalEvent) ?? run.completedAt ?? void 0;
|
|
1336
|
-
const endTime = completedAt ?? now;
|
|
1337
|
-
const { input: _i, output: _o, error: _e, ...runIdentity } = run;
|
|
1554
|
+
if (!step) {
|
|
1555
|
+
return null;
|
|
1556
|
+
}
|
|
1557
|
+
const parsedName = parseStepName(String(step.stepName));
|
|
1338
1558
|
const attributes = {
|
|
1339
|
-
resource: "
|
|
1340
|
-
data:
|
|
1341
|
-
...runIdentity,
|
|
1342
|
-
createdAt: spanStartTime,
|
|
1343
|
-
startedAt: activeStartTime,
|
|
1344
|
-
completedAt
|
|
1345
|
-
}
|
|
1559
|
+
resource: "step",
|
|
1560
|
+
data: step
|
|
1346
1561
|
};
|
|
1347
|
-
const
|
|
1562
|
+
const resource = "step";
|
|
1563
|
+
const events = convertEventsToSpanEvents(stepEvents, false, {
|
|
1348
1564
|
preferOccurredAt: true
|
|
1349
1565
|
});
|
|
1566
|
+
const spanStartEvent = stepEvents.find((event) => event.eventType === "step_created") ?? stepEvents[0];
|
|
1567
|
+
const spanStartTime = getEventTimestamp(spanStartEvent) ?? new Date(step.createdAt);
|
|
1568
|
+
let activeStartTime = step.startedAt ? new Date(step.startedAt) : void 0;
|
|
1569
|
+
const firstStartEvent = stepEvents.find((event) => event.eventType === "step_started");
|
|
1570
|
+
if (firstStartEvent) {
|
|
1571
|
+
activeStartTime = getEventTimestamp(firstStartEvent) ?? new Date(firstStartEvent.createdAt);
|
|
1572
|
+
}
|
|
1573
|
+
let endTime = new Date(maxEndTime);
|
|
1574
|
+
if (step.completedAt) {
|
|
1575
|
+
const completedEvent = stepEvents.slice().reverse().find((event) => event.eventType === "step_completed" || event.eventType === "step_failed");
|
|
1576
|
+
endTime = getEventTimestamp(completedEvent) ?? new Date(step.completedAt);
|
|
1577
|
+
}
|
|
1350
1578
|
return {
|
|
1351
|
-
spanId: String(
|
|
1352
|
-
name:
|
|
1579
|
+
spanId: String(step.stepId),
|
|
1580
|
+
name: (parsedName == null ? void 0 : parsedName.shortName) ?? String(step.stepName),
|
|
1353
1581
|
kind: 1,
|
|
1354
1582
|
// INTERNAL span kind
|
|
1355
|
-
resource
|
|
1583
|
+
resource,
|
|
1356
1584
|
library: WORKFLOW_LIBRARY,
|
|
1357
1585
|
status: { code: 0 },
|
|
1358
1586
|
traceFlags: 1,
|
|
@@ -1366,391 +1594,199 @@ function runToSpan(run, runEvents, nowTime) {
|
|
|
1366
1594
|
activeStartTime: activeStartTime && activeStartTime.getTime() > spanStartTime.getTime() ? dateToOtelTime(activeStartTime) : void 0
|
|
1367
1595
|
};
|
|
1368
1596
|
}
|
|
1369
|
-
const
|
|
1370
|
-
|
|
1371
|
-
const
|
|
1372
|
-
|
|
1373
|
-
function filterSpanRawEvents(events, resource, spanId) {
|
|
1374
|
-
if (resource === "run") {
|
|
1375
|
-
return events.filter(isRunLevelEvent);
|
|
1376
|
-
}
|
|
1377
|
-
if (!spanId)
|
|
1378
|
-
return [];
|
|
1379
|
-
return events.filter((e) => e.correlationId === spanId);
|
|
1380
|
-
}
|
|
1381
|
-
function pushEvent(map, correlationId, event) {
|
|
1382
|
-
const existing = map.get(correlationId);
|
|
1383
|
-
if (existing) {
|
|
1384
|
-
existing.push(event);
|
|
1385
|
-
return;
|
|
1386
|
-
}
|
|
1387
|
-
map.set(correlationId, [event]);
|
|
1388
|
-
}
|
|
1389
|
-
function groupEventsByCorrelation(events) {
|
|
1390
|
-
const eventsByStepId = /* @__PURE__ */ new Map();
|
|
1391
|
-
const runLevelEvents = [];
|
|
1392
|
-
const timerEvents = /* @__PURE__ */ new Map();
|
|
1393
|
-
const hookEvents = /* @__PURE__ */ new Map();
|
|
1394
|
-
for (const event of events) {
|
|
1395
|
-
const correlationId = event.correlationId;
|
|
1396
|
-
if (!correlationId) {
|
|
1397
|
-
runLevelEvents.push(event);
|
|
1398
|
-
continue;
|
|
1399
|
-
}
|
|
1400
|
-
if (isTimerEvent(event.eventType)) {
|
|
1401
|
-
pushEvent(timerEvents, correlationId, event);
|
|
1402
|
-
continue;
|
|
1403
|
-
}
|
|
1404
|
-
if (isHookLifecycleEvent(event.eventType)) {
|
|
1405
|
-
pushEvent(hookEvents, correlationId, event);
|
|
1406
|
-
continue;
|
|
1407
|
-
}
|
|
1408
|
-
if (isStepEvent(event.eventType)) {
|
|
1409
|
-
pushEvent(eventsByStepId, correlationId, event);
|
|
1410
|
-
continue;
|
|
1411
|
-
}
|
|
1412
|
-
runLevelEvents.push(event);
|
|
1413
|
-
}
|
|
1414
|
-
return { eventsByStepId, runLevelEvents, timerEvents, hookEvents };
|
|
1415
|
-
}
|
|
1416
|
-
function computeLatestKnownTime(events, run) {
|
|
1417
|
-
let latest = new Date(run.createdAt).getTime();
|
|
1418
|
-
for (const event of events) {
|
|
1419
|
-
const t = (getEventTimestamp(event) ?? new Date(event.createdAt)).getTime();
|
|
1420
|
-
if (t > latest)
|
|
1421
|
-
latest = t;
|
|
1422
|
-
}
|
|
1423
|
-
return new Date(latest);
|
|
1424
|
-
}
|
|
1425
|
-
function buildSpans(run, groupedEvents, now, latestKnownTime) {
|
|
1426
|
-
const childMaxEnd = latestKnownTime;
|
|
1427
|
-
const runMaxEnd = run.completedAt ?? now;
|
|
1428
|
-
const stepSpans = Array.from(groupedEvents.eventsByStepId.values()).map((events) => stepToSpan(events, childMaxEnd)).filter((span) => span !== null);
|
|
1429
|
-
const hookSpans = Array.from(groupedEvents.hookEvents.values()).map((events) => hookToSpan(events, childMaxEnd)).filter((span) => span !== null);
|
|
1430
|
-
const waitSpans = Array.from(groupedEvents.timerEvents.values()).map((events) => waitToSpan(events, childMaxEnd, runMaxEnd)).filter((span) => span !== null);
|
|
1431
|
-
return {
|
|
1432
|
-
runSpan: runToSpan(run, groupedEvents.runLevelEvents, now),
|
|
1433
|
-
spans: [...stepSpans, ...hookSpans, ...waitSpans]
|
|
1434
|
-
};
|
|
1435
|
-
}
|
|
1436
|
-
function cascadeSpans(runSpan, spans) {
|
|
1437
|
-
const sortedSpans = [
|
|
1438
|
-
runSpan,
|
|
1439
|
-
...spans.slice().sort((a, b) => {
|
|
1440
|
-
const aStart = otelTimeToMs(a.startTime);
|
|
1441
|
-
const bStart = otelTimeToMs(b.startTime);
|
|
1442
|
-
return aStart - bStart;
|
|
1443
|
-
})
|
|
1444
|
-
];
|
|
1445
|
-
return sortedSpans.map((span, index) => {
|
|
1446
|
-
const parentSpanId = index === 0 ? void 0 : String(sortedSpans[index - 1].spanId);
|
|
1447
|
-
return {
|
|
1448
|
-
...span,
|
|
1449
|
-
parentSpanId
|
|
1450
|
-
};
|
|
1451
|
-
});
|
|
1452
|
-
}
|
|
1453
|
-
function buildTrace(run, events, now) {
|
|
1454
|
-
const groupedEvents = groupEventsByCorrelation(events);
|
|
1455
|
-
const latestKnownTime = computeLatestKnownTime(events, run);
|
|
1456
|
-
const { runSpan, spans } = buildSpans(run, groupedEvents, now, latestKnownTime);
|
|
1457
|
-
const sortedCascadingSpans = cascadeSpans(runSpan, spans);
|
|
1458
|
-
const traceStartMs = otelTimeToMs(runSpan.startTime);
|
|
1459
|
-
const knownDurationMs = latestKnownTime.getTime() - traceStartMs;
|
|
1460
|
-
return {
|
|
1461
|
-
traceId: run.runId,
|
|
1462
|
-
rootSpanId: run.runId,
|
|
1463
|
-
spans: sortedCascadingSpans,
|
|
1464
|
-
resources: [
|
|
1465
|
-
{
|
|
1466
|
-
name: "workflow",
|
|
1467
|
-
attributes: {
|
|
1468
|
-
"service.name": WORKFLOW_LIBRARY.name
|
|
1469
|
-
}
|
|
1470
|
-
}
|
|
1471
|
-
],
|
|
1472
|
-
knownDurationMs: Math.max(0, knownDurationMs)
|
|
1473
|
-
};
|
|
1474
|
-
}
|
|
1475
|
-
const ELLIPSIS = "...";
|
|
1476
|
-
const MIN_START = 3;
|
|
1477
|
-
const MIN_END = 3;
|
|
1478
|
-
const MIN_KEPT = MIN_START + MIN_END;
|
|
1479
|
-
const graphemeSegmenter = typeof Intl !== "undefined" && "Segmenter" in Intl ? new Intl.Segmenter(void 0, { granularity: "grapheme" }) : null;
|
|
1480
|
-
function toGraphemes(text) {
|
|
1481
|
-
if (graphemeSegmenter) {
|
|
1482
|
-
return [...graphemeSegmenter.segment(text)].map((s) => s.segment);
|
|
1483
|
-
}
|
|
1484
|
-
return Array.from(text);
|
|
1485
|
-
}
|
|
1486
|
-
function buildCandidate(graphemes, kept) {
|
|
1487
|
-
if (kept <= 0) {
|
|
1488
|
-
return {
|
|
1489
|
-
prefixText: "",
|
|
1490
|
-
prefixGraphemeCount: 0,
|
|
1491
|
-
suffixText: "",
|
|
1492
|
-
suffixGraphemeCount: 0,
|
|
1493
|
-
text: ELLIPSIS,
|
|
1494
|
-
truncated: true
|
|
1495
|
-
};
|
|
1496
|
-
}
|
|
1497
|
-
const suffixGraphemeCount = kept >= MIN_KEPT ? Math.max(MIN_END, Math.floor(kept / 2)) : Math.floor(kept / 2);
|
|
1498
|
-
const prefixGraphemeCount = kept - suffixGraphemeCount;
|
|
1499
|
-
const prefixText = graphemes.slice(0, prefixGraphemeCount).join("");
|
|
1500
|
-
const suffixText = suffixGraphemeCount > 0 ? graphemes.slice(-suffixGraphemeCount).join("") : "";
|
|
1501
|
-
return {
|
|
1502
|
-
prefixText,
|
|
1503
|
-
prefixGraphemeCount,
|
|
1504
|
-
suffixText,
|
|
1505
|
-
suffixGraphemeCount,
|
|
1506
|
-
text: prefixText + ELLIPSIS + suffixText,
|
|
1507
|
-
truncated: true
|
|
1508
|
-
};
|
|
1509
|
-
}
|
|
1510
|
-
function middleTruncate(graphemes, availableWidth, measure, fullWidth) {
|
|
1511
|
-
const fullText = graphemes.join("");
|
|
1512
|
-
const resolvedFullWidth = fullWidth ?? measure(fullText);
|
|
1513
|
-
if (availableWidth <= 0 || graphemes.length === 0) {
|
|
1514
|
-
return {
|
|
1515
|
-
prefixText: fullText,
|
|
1516
|
-
prefixGraphemeCount: graphemes.length,
|
|
1517
|
-
suffixText: "",
|
|
1518
|
-
suffixGraphemeCount: 0,
|
|
1519
|
-
text: fullText,
|
|
1520
|
-
truncated: false
|
|
1521
|
-
};
|
|
1522
|
-
}
|
|
1523
|
-
if (resolvedFullWidth <= availableWidth) {
|
|
1524
|
-
return {
|
|
1525
|
-
prefixText: fullText,
|
|
1526
|
-
prefixGraphemeCount: graphemes.length,
|
|
1527
|
-
suffixText: "",
|
|
1528
|
-
suffixGraphemeCount: 0,
|
|
1529
|
-
text: fullText,
|
|
1530
|
-
truncated: false
|
|
1531
|
-
};
|
|
1532
|
-
}
|
|
1533
|
-
let lo = 0;
|
|
1534
|
-
let hi = graphemes.length - 1;
|
|
1535
|
-
let best = -1;
|
|
1536
|
-
while (lo <= hi) {
|
|
1537
|
-
const mid = lo + hi >>> 1;
|
|
1538
|
-
const candidate = buildCandidate(graphemes, mid);
|
|
1539
|
-
if (measure(candidate.text) <= availableWidth) {
|
|
1540
|
-
best = mid;
|
|
1541
|
-
lo = mid + 1;
|
|
1542
|
-
} else {
|
|
1543
|
-
hi = mid - 1;
|
|
1544
|
-
}
|
|
1545
|
-
}
|
|
1546
|
-
if (best === -1) {
|
|
1547
|
-
return {
|
|
1548
|
-
prefixText: "",
|
|
1549
|
-
prefixGraphemeCount: 0,
|
|
1550
|
-
suffixText: "",
|
|
1551
|
-
suffixGraphemeCount: 0,
|
|
1552
|
-
text: "",
|
|
1553
|
-
truncated: true
|
|
1554
|
-
};
|
|
1555
|
-
}
|
|
1556
|
-
return buildCandidate(graphemes, best);
|
|
1557
|
-
}
|
|
1558
|
-
function getMiddleTruncateCopyText({ prefixText, selectionEnd, selectionStart, suffixText, value }) {
|
|
1559
|
-
const visibleText = prefixText + ELLIPSIS + suffixText;
|
|
1560
|
-
if (selectionStart < 0 || selectionEnd > visibleText.length || selectionStart >= selectionEnd) {
|
|
1561
|
-
return null;
|
|
1562
|
-
}
|
|
1563
|
-
if (selectionStart === 0 && selectionEnd === visibleText.length) {
|
|
1564
|
-
return value;
|
|
1565
|
-
}
|
|
1566
|
-
const ellipsisStart = prefixText.length;
|
|
1567
|
-
const ellipsisEnd = ellipsisStart + ELLIPSIS.length;
|
|
1568
|
-
if (selectionStart > ellipsisStart || selectionEnd < ellipsisEnd) {
|
|
1569
|
-
return null;
|
|
1570
|
-
}
|
|
1571
|
-
const originalGraphemes = toGraphemes(value);
|
|
1572
|
-
const selectedPrefixGraphemeCount = toGraphemes(visibleText.slice(0, selectionStart)).length;
|
|
1573
|
-
const selectedSuffixGraphemeCount = toGraphemes(visibleText.slice(ellipsisEnd, selectionEnd)).length;
|
|
1574
|
-
const suffixStart = originalGraphemes.length - toGraphemes(suffixText).length;
|
|
1575
|
-
return originalGraphemes.slice(selectedPrefixGraphemeCount, suffixStart + selectedSuffixGraphemeCount).join("");
|
|
1576
|
-
}
|
|
1577
|
-
function getMiddleTruncateCopyTextFromSelectionText({ prefixText, selectionText, suffixText, value }) {
|
|
1578
|
-
const visibleText = prefixText + ELLIPSIS + suffixText;
|
|
1579
|
-
const trimmedSelectionText = selectionText.trim();
|
|
1580
|
-
if (!trimmedSelectionText) {
|
|
1581
|
-
return null;
|
|
1582
|
-
}
|
|
1583
|
-
const leading = selectionText.slice(0, selectionText.length - selectionText.trimStart().length);
|
|
1584
|
-
const trailing = selectionText.slice(selectionText.trimEnd().length);
|
|
1585
|
-
if (trimmedSelectionText === visibleText) {
|
|
1586
|
-
return leading + value + trailing;
|
|
1587
|
-
}
|
|
1588
|
-
if (!trimmedSelectionText.includes(ELLIPSIS)) {
|
|
1597
|
+
const hookEventsToHookEntity = (events) => {
|
|
1598
|
+
var _a;
|
|
1599
|
+
const createdEvent = events.find((event) => event.eventType === "hook_created");
|
|
1600
|
+
if (!createdEvent) {
|
|
1589
1601
|
return null;
|
|
1590
1602
|
}
|
|
1591
|
-
const
|
|
1592
|
-
|
|
1603
|
+
const receivedEvents = events.filter((event) => event.eventType === "hook_received");
|
|
1604
|
+
const disposedEvents = events.filter((event) => event.eventType === "hook_disposed");
|
|
1605
|
+
const lastReceivedEvent = receivedEvents.at(-1);
|
|
1606
|
+
return {
|
|
1607
|
+
hookId: createdEvent.correlationId,
|
|
1608
|
+
runId: createdEvent.runId,
|
|
1609
|
+
token: (_a = createdEvent.eventData) == null ? void 0 : _a.token,
|
|
1610
|
+
createdAt: getEventTimestamp(createdEvent) ?? createdEvent.createdAt,
|
|
1611
|
+
receivedCount: receivedEvents.length,
|
|
1612
|
+
lastReceivedAt: getEventTimestamp(lastReceivedEvent),
|
|
1613
|
+
disposedAt: getEventTimestamp(disposedEvents.at(-1))
|
|
1614
|
+
};
|
|
1615
|
+
};
|
|
1616
|
+
function hookToSpan(hookEvents, maxEndTime) {
|
|
1617
|
+
const hook = hookEventsToHookEntity(hookEvents);
|
|
1618
|
+
if (!hook) {
|
|
1593
1619
|
return null;
|
|
1594
1620
|
}
|
|
1595
|
-
const
|
|
1596
|
-
const
|
|
1597
|
-
prefixText,
|
|
1598
|
-
selectionEnd,
|
|
1599
|
-
selectionStart,
|
|
1600
|
-
suffixText,
|
|
1601
|
-
value
|
|
1602
|
-
});
|
|
1603
|
-
return mappedText === null ? null : leading + mappedText + trailing;
|
|
1604
|
-
}
|
|
1605
|
-
const useIsomorphicLayoutEffect = typeof window === "undefined" ? reactExports.useEffect : reactExports.useLayoutEffect;
|
|
1606
|
-
function createFullState(value, graphemes) {
|
|
1621
|
+
const events = convertEventsToSpanEvents(hookEvents, false);
|
|
1622
|
+
const endTime = hook.disposedAt || maxEndTime;
|
|
1607
1623
|
return {
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1624
|
+
spanId: String(hook.hookId),
|
|
1625
|
+
name: hook.token ?? String(hook.hookId),
|
|
1626
|
+
kind: 1,
|
|
1627
|
+
// INTERNAL span kind
|
|
1628
|
+
resource: "hook",
|
|
1629
|
+
library: WORKFLOW_LIBRARY,
|
|
1630
|
+
status: { code: 1 },
|
|
1631
|
+
traceFlags: 1,
|
|
1632
|
+
attributes: {
|
|
1633
|
+
resource: "hook",
|
|
1634
|
+
data: hook
|
|
1635
|
+
},
|
|
1636
|
+
links: [],
|
|
1637
|
+
events,
|
|
1638
|
+
startTime: dateToOtelTime(hook.createdAt),
|
|
1639
|
+
endTime: dateToOtelTime(endTime),
|
|
1640
|
+
duration: calculateDuration(hook.createdAt, endTime)
|
|
1614
1641
|
};
|
|
1615
1642
|
}
|
|
1616
|
-
function
|
|
1617
|
-
|
|
1618
|
-
const
|
|
1619
|
-
const
|
|
1620
|
-
const
|
|
1621
|
-
const
|
|
1622
|
-
const
|
|
1623
|
-
const
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
if (!el || !measureEl)
|
|
1635
|
-
return;
|
|
1636
|
-
const available = el.clientWidth;
|
|
1637
|
-
if (available <= 0) {
|
|
1638
|
-
updateState(fullState);
|
|
1639
|
-
return;
|
|
1640
|
-
}
|
|
1641
|
-
const measure = (text) => {
|
|
1642
|
-
measureEl.textContent = text;
|
|
1643
|
-
return measureEl.scrollWidth;
|
|
1644
|
-
};
|
|
1645
|
-
const fullWidth = measure(value);
|
|
1646
|
-
if (fullWidth <= available) {
|
|
1647
|
-
updateState(fullState);
|
|
1648
|
-
return;
|
|
1643
|
+
function runToSpan(run, runEvents, nowTime) {
|
|
1644
|
+
var _a;
|
|
1645
|
+
const now = nowTime ?? /* @__PURE__ */ new Date();
|
|
1646
|
+
const runCreatedEvent = runEvents.find((event) => event.eventType === "run_created");
|
|
1647
|
+
const runStartedEvent = runEvents.find((event) => event.eventType === "run_started");
|
|
1648
|
+
const terminalEvent = runEvents.slice().reverse().find((event) => event.eventType === "run_completed" || event.eventType === "run_failed" || event.eventType === "run_cancelled");
|
|
1649
|
+
const spanStartTime = getEventTimestamp(runCreatedEvent) ?? new Date(run.createdAt);
|
|
1650
|
+
const activeStartTime = getEventTimestamp(runStartedEvent) ?? (run.startedAt ? new Date(run.startedAt) : void 0);
|
|
1651
|
+
const completedAt = getEventTimestamp(terminalEvent) ?? run.completedAt ?? void 0;
|
|
1652
|
+
const endTime = completedAt ?? now;
|
|
1653
|
+
const { input: _i, output: _o, error: _e, ...runIdentity } = run;
|
|
1654
|
+
const attributes = {
|
|
1655
|
+
resource: "run",
|
|
1656
|
+
data: {
|
|
1657
|
+
...runIdentity,
|
|
1658
|
+
createdAt: spanStartTime,
|
|
1659
|
+
startedAt: activeStartTime,
|
|
1660
|
+
completedAt
|
|
1649
1661
|
}
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
prefixGraphemeCount: result.prefixGraphemeCount,
|
|
1655
|
-
prefixText: result.prefixText,
|
|
1656
|
-
suffixGraphemeCount: result.suffixGraphemeCount,
|
|
1657
|
-
suffixText: result.suffixText
|
|
1658
|
-
});
|
|
1659
|
-
}, [fullState, graphemes, updateState, value]);
|
|
1660
|
-
useIsomorphicLayoutEffect(() => {
|
|
1661
|
-
recalculate();
|
|
1662
|
-
}, [recalculate]);
|
|
1663
|
-
reactExports.useEffect(() => {
|
|
1664
|
-
var _a;
|
|
1665
|
-
const el = ref.current;
|
|
1666
|
-
if (!el)
|
|
1667
|
-
return;
|
|
1668
|
-
const debouncedRecalc = () => {
|
|
1669
|
-
cancelAnimationFrame(rafRef.current);
|
|
1670
|
-
rafRef.current = requestAnimationFrame(recalculate);
|
|
1671
|
-
};
|
|
1672
|
-
const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(debouncedRecalc) : null;
|
|
1673
|
-
ro == null ? void 0 : ro.observe(el);
|
|
1674
|
-
window.addEventListener("resize", debouncedRecalc);
|
|
1675
|
-
const onFontsLoaded = () => {
|
|
1676
|
-
debouncedRecalc();
|
|
1677
|
-
};
|
|
1678
|
-
const fontSet = "fonts" in document ? document.fonts : null;
|
|
1679
|
-
(_a = fontSet == null ? void 0 : fontSet.addEventListener) == null ? void 0 : _a.call(fontSet, "loadingdone", onFontsLoaded);
|
|
1680
|
-
return () => {
|
|
1681
|
-
var _a2;
|
|
1682
|
-
ro == null ? void 0 : ro.disconnect();
|
|
1683
|
-
window.removeEventListener("resize", debouncedRecalc);
|
|
1684
|
-
cancelAnimationFrame(rafRef.current);
|
|
1685
|
-
(_a2 = fontSet == null ? void 0 : fontSet.removeEventListener) == null ? void 0 : _a2.call(fontSet, "loadingdone", onFontsLoaded);
|
|
1686
|
-
};
|
|
1687
|
-
}, [recalculate]);
|
|
1662
|
+
};
|
|
1663
|
+
const events = convertEventsToSpanEvents(runEvents, false, {
|
|
1664
|
+
preferOccurredAt: true
|
|
1665
|
+
});
|
|
1688
1666
|
return {
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1667
|
+
spanId: String(run.runId),
|
|
1668
|
+
name: String(((_a = parseWorkflowName(run.workflowName)) == null ? void 0 : _a.shortName) ?? "?"),
|
|
1669
|
+
kind: 1,
|
|
1670
|
+
// INTERNAL span kind
|
|
1671
|
+
resource: "run",
|
|
1672
|
+
library: WORKFLOW_LIBRARY,
|
|
1673
|
+
status: { code: 0 },
|
|
1674
|
+
traceFlags: 1,
|
|
1675
|
+
attributes,
|
|
1676
|
+
links: [],
|
|
1677
|
+
events,
|
|
1678
|
+
startTime: dateToOtelTime(spanStartTime),
|
|
1679
|
+
endTime: dateToOtelTime(endTime),
|
|
1680
|
+
duration: calculateDuration(spanStartTime, endTime),
|
|
1681
|
+
// Only set activeStartTime if it differs from startTime (i.e., there was a queued period)
|
|
1682
|
+
activeStartTime: activeStartTime && activeStartTime.getTime() > spanStartTime.getTime() ? dateToOtelTime(activeStartTime) : void 0
|
|
1697
1683
|
};
|
|
1698
1684
|
}
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1685
|
+
const isStepEvent = (eventType) => eventType.startsWith("step_");
|
|
1686
|
+
const isTimerEvent = (eventType) => eventType === "wait_created" || eventType === "wait_completed";
|
|
1687
|
+
const isHookLifecycleEvent = (eventType) => eventType === "hook_received" || eventType === "hook_created" || eventType === "hook_disposed";
|
|
1688
|
+
const isRunLevelEvent = (event) => !event.correlationId || !isTimerEvent(event.eventType) && !isHookLifecycleEvent(event.eventType) && !isStepEvent(event.eventType);
|
|
1689
|
+
function filterSpanRawEvents(events, resource, spanId) {
|
|
1690
|
+
if (resource === "run") {
|
|
1691
|
+
return events.filter(isRunLevelEvent);
|
|
1702
1692
|
}
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1693
|
+
if (!spanId)
|
|
1694
|
+
return [];
|
|
1695
|
+
return events.filter((e) => e.correlationId === spanId);
|
|
1696
|
+
}
|
|
1697
|
+
function pushEvent(map, correlationId, event) {
|
|
1698
|
+
const existing = map.get(correlationId);
|
|
1699
|
+
if (existing) {
|
|
1700
|
+
existing.push(event);
|
|
1701
|
+
return;
|
|
1702
|
+
}
|
|
1703
|
+
map.set(correlationId, [event]);
|
|
1704
|
+
}
|
|
1705
|
+
function groupEventsByCorrelation(events) {
|
|
1706
|
+
const eventsByStepId = /* @__PURE__ */ new Map();
|
|
1707
|
+
const runLevelEvents = [];
|
|
1708
|
+
const timerEvents = /* @__PURE__ */ new Map();
|
|
1709
|
+
const hookEvents = /* @__PURE__ */ new Map();
|
|
1710
|
+
for (const event of events) {
|
|
1711
|
+
const correlationId = event.correlationId;
|
|
1712
|
+
if (!correlationId) {
|
|
1713
|
+
runLevelEvents.push(event);
|
|
1714
|
+
continue;
|
|
1715
|
+
}
|
|
1716
|
+
if (isTimerEvent(event.eventType)) {
|
|
1717
|
+
pushEvent(timerEvents, correlationId, event);
|
|
1718
|
+
continue;
|
|
1719
|
+
}
|
|
1720
|
+
if (isHookLifecycleEvent(event.eventType)) {
|
|
1721
|
+
pushEvent(hookEvents, correlationId, event);
|
|
1722
|
+
continue;
|
|
1723
|
+
}
|
|
1724
|
+
if (isStepEvent(event.eventType)) {
|
|
1725
|
+
pushEvent(eventsByStepId, correlationId, event);
|
|
1726
|
+
continue;
|
|
1727
|
+
}
|
|
1728
|
+
runLevelEvents.push(event);
|
|
1729
|
+
}
|
|
1730
|
+
return { eventsByStepId, runLevelEvents, timerEvents, hookEvents };
|
|
1731
|
+
}
|
|
1732
|
+
function computeLatestKnownTime(events, run) {
|
|
1733
|
+
let latest = new Date(run.createdAt).getTime();
|
|
1734
|
+
for (const event of events) {
|
|
1735
|
+
const t = (getEventTimestamp(event) ?? new Date(event.createdAt)).getTime();
|
|
1736
|
+
if (t > latest)
|
|
1737
|
+
latest = t;
|
|
1738
|
+
}
|
|
1739
|
+
return new Date(latest);
|
|
1740
|
+
}
|
|
1741
|
+
function buildSpans(run, groupedEvents, now, latestKnownTime) {
|
|
1742
|
+
const childMaxEnd = latestKnownTime;
|
|
1743
|
+
const runMaxEnd = run.completedAt ?? now;
|
|
1744
|
+
const stepSpans = Array.from(groupedEvents.eventsByStepId.values()).map((events) => stepToSpan(events, childMaxEnd)).filter((span) => span !== null);
|
|
1745
|
+
const hookSpans = Array.from(groupedEvents.hookEvents.values()).map((events) => hookToSpan(events, childMaxEnd)).filter((span) => span !== null);
|
|
1746
|
+
const waitSpans = Array.from(groupedEvents.timerEvents.values()).map((events) => waitToSpan(events, childMaxEnd, runMaxEnd)).filter((span) => span !== null);
|
|
1709
1747
|
return {
|
|
1710
|
-
|
|
1711
|
-
|
|
1748
|
+
runSpan: runToSpan(run, groupedEvents.runLevelEvents, now),
|
|
1749
|
+
spans: [...stepSpans, ...hookSpans, ...waitSpans]
|
|
1712
1750
|
};
|
|
1713
1751
|
}
|
|
1714
|
-
function
|
|
1715
|
-
const
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
return;
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
const
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1752
|
+
function cascadeSpans(runSpan, spans) {
|
|
1753
|
+
const sortedSpans = [
|
|
1754
|
+
runSpan,
|
|
1755
|
+
...spans.slice().sort((a, b) => {
|
|
1756
|
+
const aStart = otelTimeToMs(a.startTime);
|
|
1757
|
+
const bStart = otelTimeToMs(b.startTime);
|
|
1758
|
+
return aStart - bStart;
|
|
1759
|
+
})
|
|
1760
|
+
];
|
|
1761
|
+
return sortedSpans.map((span, index) => {
|
|
1762
|
+
const parentSpanId = index === 0 ? void 0 : String(sortedSpans[index - 1].spanId);
|
|
1763
|
+
return {
|
|
1764
|
+
...span,
|
|
1765
|
+
parentSpanId
|
|
1766
|
+
};
|
|
1767
|
+
});
|
|
1768
|
+
}
|
|
1769
|
+
function buildTrace(run, events, now) {
|
|
1770
|
+
const groupedEvents = groupEventsByCorrelation(events);
|
|
1771
|
+
const latestKnownTime = computeLatestKnownTime(events, run);
|
|
1772
|
+
const { runSpan, spans } = buildSpans(run, groupedEvents, now, latestKnownTime);
|
|
1773
|
+
const sortedCascadingSpans = cascadeSpans(runSpan, spans);
|
|
1774
|
+
const traceStartMs = otelTimeToMs(runSpan.startTime);
|
|
1775
|
+
const knownDurationMs = latestKnownTime.getTime() - traceStartMs;
|
|
1776
|
+
return {
|
|
1777
|
+
traceId: run.runId,
|
|
1778
|
+
rootSpanId: run.runId,
|
|
1779
|
+
spans: sortedCascadingSpans,
|
|
1780
|
+
resources: [
|
|
1781
|
+
{
|
|
1782
|
+
name: "workflow",
|
|
1783
|
+
attributes: {
|
|
1784
|
+
"service.name": WORKFLOW_LIBRARY.name
|
|
1785
|
+
}
|
|
1740
1786
|
}
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
selectionText,
|
|
1745
|
-
suffixText,
|
|
1746
|
-
value
|
|
1747
|
-
}));
|
|
1748
|
-
if (copyText === null)
|
|
1749
|
-
return;
|
|
1750
|
-
e.preventDefault();
|
|
1751
|
-
e.clipboardData.setData("text/plain", copyText);
|
|
1752
|
-
}, [onCopyProp, isTruncated, prefixText, suffixText, value]);
|
|
1753
|
-
return jsxRuntimeExports.jsxs("span", { title: isTruncated ? value : void 0, ...props, ref, className: cn("relative inline-grid min-w-0 max-w-full overflow-hidden whitespace-nowrap", className), onCopy: handleCopy, children: [isTruncated && jsxRuntimeExports.jsx("span", { className: "sr-only select-none", children: value }), jsxRuntimeExports.jsx("span", { "aria-hidden": "true", className: "pointer-events-none col-start-1 row-start-1 invisible select-none whitespace-nowrap", children: value }), jsxRuntimeExports.jsx("span", { "aria-hidden": isTruncated || void 0, className: "col-start-1 row-start-1 min-w-0 overflow-hidden", ref: visibleRef, children: isTruncated ? jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("span", { children: prefixText }), jsxRuntimeExports.jsx("span", { children: ELLIPSIS }), jsxRuntimeExports.jsx("span", { children: suffixText })] }) : displayText }), jsxRuntimeExports.jsx("span", { "aria-hidden": "true", className: "pointer-events-none absolute left-0 top-0 inline-block invisible select-none whitespace-nowrap", ref: measureRef })] });
|
|
1787
|
+
],
|
|
1788
|
+
knownDurationMs: Math.max(0, knownDurationMs)
|
|
1789
|
+
};
|
|
1754
1790
|
}
|
|
1755
1791
|
function ConversationView({ messages }) {
|
|
1756
1792
|
if (messages.length === 0) {
|
|
@@ -1897,7 +1933,7 @@ const conversationTabs = [
|
|
|
1897
1933
|
];
|
|
1898
1934
|
function ConversationWithTabs({ conversation, args }) {
|
|
1899
1935
|
const [activeTab, setActiveTab] = reactExports.useState("conversation");
|
|
1900
|
-
return jsxRuntimeExports.jsx(
|
|
1936
|
+
return jsxRuntimeExports.jsx(Collapsible, { label: "Input", children: jsxRuntimeExports.jsx(TabbedContainer, { tabs: conversationTabs, activeTab, onTabChange: setActiveTab, ariaLabel: "Conversation view", children: activeTab === "conversation" ? jsxRuntimeExports.jsx(ConversationView, { messages: conversation }) : jsxRuntimeExports.jsx("div", { className: "p-3", children: Array.isArray(args) ? args.map((v, i) => jsxRuntimeExports.jsx("div", { className: "mt-2 first:mt-0", children: JsonBlock(v) }, i)) : JsonBlock(args) }) }) });
|
|
1901
1937
|
}
|
|
1902
1938
|
function EncryptedFieldBlock() {
|
|
1903
1939
|
return jsxRuntimeExports.jsx(EncryptedDataBlock, {});
|
|
@@ -2069,7 +2105,7 @@ const attributeToDisplayFn = {
|
|
|
2069
2105
|
environment: (_value) => null,
|
|
2070
2106
|
executionContext: (_value) => null,
|
|
2071
2107
|
// Attributes — string-string metadata attached to the run.
|
|
2072
|
-
// Rendered as key-value rows in its own collapsible
|
|
2108
|
+
// Rendered as key-value rows in its own collapsible section;
|
|
2073
2109
|
// if empty/missing, hidden by the hasDisplayContent gate.
|
|
2074
2110
|
attributes: (value) => {
|
|
2075
2111
|
if (!hasDisplayContent(value))
|
|
@@ -2089,15 +2125,17 @@ const attributeToDisplayFn = {
|
|
|
2089
2125
|
metadata: (value) => {
|
|
2090
2126
|
if (!hasDisplayContent(value))
|
|
2091
2127
|
return null;
|
|
2092
|
-
if (isEncryptedMarker(value))
|
|
2093
|
-
return jsxRuntimeExports.jsx(EncryptedDataBlock, {});
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2128
|
+
if (isEncryptedMarker(value)) {
|
|
2129
|
+
return jsxRuntimeExports.jsx(Collapsible, { label: "Metadata", children: jsxRuntimeExports.jsx(EncryptedDataBlock, {}) });
|
|
2130
|
+
}
|
|
2131
|
+
if (isExpiredMarker(value)) {
|
|
2132
|
+
return jsxRuntimeExports.jsx(Collapsible, { label: "Metadata", children: jsxRuntimeExports.jsx(ExpiredFieldBlock, {}) });
|
|
2133
|
+
}
|
|
2134
|
+
return jsxRuntimeExports.jsx(RunMetadataCard, { metadata: value });
|
|
2097
2135
|
},
|
|
2098
2136
|
input: (value, context) => {
|
|
2099
2137
|
if (isEncryptedMarker(value)) {
|
|
2100
|
-
return jsxRuntimeExports.jsx(
|
|
2138
|
+
return jsxRuntimeExports.jsx(Collapsible, { label: "Input", children: jsxRuntimeExports.jsx(EncryptedFieldBlock, {}) });
|
|
2101
2139
|
}
|
|
2102
2140
|
if (isExpiredMarker(value))
|
|
2103
2141
|
return jsxRuntimeExports.jsx(ExpiredFieldBlock, {});
|
|
@@ -2109,51 +2147,51 @@ const attributeToDisplayFn = {
|
|
|
2109
2147
|
if ((context == null ? void 0 : context.stepName) && isDoStreamStep(context.stepName)) {
|
|
2110
2148
|
const conversation = extractConversation(args);
|
|
2111
2149
|
if (conversation && conversation.length > 0) {
|
|
2112
|
-
return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx(ConversationWithTabs, { conversation, args }), hasClosureVars && jsxRuntimeExports.jsx(
|
|
2150
|
+
return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx(ConversationWithTabs, { conversation, args }), hasClosureVars && jsxRuntimeExports.jsx(Collapsible, { label: "Closure Variables", children: JsonBlock(closureVars) }), hasThisVal && jsxRuntimeExports.jsx(Collapsible, { label: "This Value", children: JsonBlock(thisVal) })] });
|
|
2113
2151
|
}
|
|
2114
2152
|
}
|
|
2115
2153
|
if (!hasArgs && !hasClosureVars && !hasThisVal) {
|
|
2116
|
-
return jsxRuntimeExports.jsx(
|
|
2154
|
+
return jsxRuntimeExports.jsx(Collapsible, { label: "Input (no data)", disabled: true });
|
|
2117
2155
|
}
|
|
2118
|
-
return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx(
|
|
2156
|
+
return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx(Collapsible, { label: "Input", children: Array.isArray(args) ? args.map((v, i) => jsxRuntimeExports.jsx("div", { className: "mt-2 first:mt-0", children: JsonBlock(v) }, i)) : JsonBlock(args) }), hasClosureVars && jsxRuntimeExports.jsx(Collapsible, { label: "Closure Variables", children: JsonBlock(closureVars) }), hasThisVal && jsxRuntimeExports.jsx(Collapsible, { label: "Context", children: JsonBlock(thisVal) })] });
|
|
2119
2157
|
}
|
|
2120
2158
|
if (!hasDisplayContent(value)) {
|
|
2121
|
-
return jsxRuntimeExports.jsx(
|
|
2159
|
+
return jsxRuntimeExports.jsx(Collapsible, { label: "Input (no data)", disabled: true });
|
|
2122
2160
|
}
|
|
2123
|
-
return jsxRuntimeExports.jsx(
|
|
2161
|
+
return jsxRuntimeExports.jsx(Collapsible, { label: "Input", children: Array.isArray(value) ? value.map((v, i) => jsxRuntimeExports.jsx("div", { className: "mt-2 first:mt-0", children: JsonBlock(v) }, i)) : JsonBlock(value) });
|
|
2124
2162
|
},
|
|
2125
2163
|
output: (value) => {
|
|
2126
2164
|
if (isEncryptedMarker(value)) {
|
|
2127
|
-
return jsxRuntimeExports.jsx(
|
|
2165
|
+
return jsxRuntimeExports.jsx(Collapsible, { label: "Output", children: jsxRuntimeExports.jsx(EncryptedFieldBlock, {}) });
|
|
2128
2166
|
}
|
|
2129
2167
|
if (!hasDisplayContent(value))
|
|
2130
2168
|
return null;
|
|
2131
2169
|
if (isExpiredMarker(value))
|
|
2132
2170
|
return jsxRuntimeExports.jsx(ExpiredFieldBlock, {});
|
|
2133
|
-
return jsxRuntimeExports.jsx(
|
|
2171
|
+
return jsxRuntimeExports.jsx(Collapsible, { label: "Output", children: JsonBlock(value) });
|
|
2134
2172
|
},
|
|
2135
2173
|
error: (value) => {
|
|
2136
2174
|
if (isEncryptedMarker(value)) {
|
|
2137
|
-
return jsxRuntimeExports.jsx(
|
|
2175
|
+
return jsxRuntimeExports.jsx(Collapsible, { label: "Error", defaultOpen: true, children: jsxRuntimeExports.jsx(EncryptedFieldBlock, {}) });
|
|
2138
2176
|
}
|
|
2139
2177
|
if (isExpiredMarker(value))
|
|
2140
2178
|
return jsxRuntimeExports.jsx(ExpiredFieldBlock, {});
|
|
2141
2179
|
if (!hasDisplayContent(value))
|
|
2142
2180
|
return null;
|
|
2143
2181
|
if (isStructuredError(value)) {
|
|
2144
|
-
return jsxRuntimeExports.jsx(
|
|
2182
|
+
return jsxRuntimeExports.jsx(Collapsible, { label: "Error", defaultOpen: true, children: jsxRuntimeExports.jsx(ErrorStackBlock, { value }) });
|
|
2145
2183
|
}
|
|
2146
|
-
return jsxRuntimeExports.jsx(
|
|
2184
|
+
return jsxRuntimeExports.jsx(Collapsible, { label: "Error", defaultOpen: true, children: JsonBlock(value) });
|
|
2147
2185
|
},
|
|
2148
2186
|
eventData: (value) => {
|
|
2149
2187
|
if (isEncryptedMarker(value)) {
|
|
2150
|
-
return jsxRuntimeExports.jsx(
|
|
2188
|
+
return jsxRuntimeExports.jsx(Collapsible, { label: "Event Data", defaultOpen: true, children: jsxRuntimeExports.jsx(EncryptedFieldBlock, {}) });
|
|
2151
2189
|
}
|
|
2152
2190
|
if (isExpiredMarker(value))
|
|
2153
2191
|
return jsxRuntimeExports.jsx(ExpiredFieldBlock, {});
|
|
2154
2192
|
if (!hasDisplayContent(value))
|
|
2155
2193
|
return null;
|
|
2156
|
-
return jsxRuntimeExports.jsx(
|
|
2194
|
+
return jsxRuntimeExports.jsx(Collapsible, { label: "Event Data", defaultOpen: true, children: JsonBlock(value) });
|
|
2157
2195
|
},
|
|
2158
2196
|
errorCode: (value) => {
|
|
2159
2197
|
if (typeof value !== "string" || value.length === 0)
|
|
@@ -2173,6 +2211,7 @@ const selfHeaderedAttributes = /* @__PURE__ */ new Set([
|
|
|
2173
2211
|
"input",
|
|
2174
2212
|
"output",
|
|
2175
2213
|
"error",
|
|
2214
|
+
"metadata",
|
|
2176
2215
|
"attributes",
|
|
2177
2216
|
"eventData"
|
|
2178
2217
|
]);
|
|
@@ -2194,9 +2233,9 @@ const AttributeBlock = ({ attribute, value, isLoading, inline = false, context }
|
|
|
2194
2233
|
if (isLoading && isExpandableLoadingTarget && !hasDisplayContent(value)) {
|
|
2195
2234
|
const label = attribute === "eventData" ? "Event Data" : attribute === "output" ? "Output" : "Input";
|
|
2196
2235
|
if (decryptCtx == null ? void 0 : decryptCtx.hasEncryptedData) {
|
|
2197
|
-
return jsxRuntimeExports.jsx(
|
|
2236
|
+
return jsxRuntimeExports.jsx(Collapsible, { label, defaultOpen: attribute === "eventData", children: jsxRuntimeExports.jsx(EncryptedFieldBlock, {}) });
|
|
2198
2237
|
}
|
|
2199
|
-
return jsxRuntimeExports.jsx(
|
|
2238
|
+
return jsxRuntimeExports.jsx(Collapsible, { label });
|
|
2200
2239
|
}
|
|
2201
2240
|
const displayFn = attributeToDisplayFn[attribute];
|
|
2202
2241
|
if (!displayFn) {
|
|
@@ -2282,12 +2321,13 @@ const AttributePanel = ({ data, moduleSpecifier, isLoading, error, expiredAt, on
|
|
|
2282
2321
|
isDecrypting,
|
|
2283
2322
|
hasEncryptedData: outerDecryptCtx == null ? void 0 : outerDecryptCtx.hasEncryptedData
|
|
2284
2323
|
} : outerDecryptCtx;
|
|
2285
|
-
return jsxRuntimeExports.jsx(ContextCardProvider, { children: jsxRuntimeExports.jsx(RunClickContext.Provider, { value: onRunClick, children: jsxRuntimeExports.jsx(StreamClickContext.Provider, { value: onStreamClick, children: jsxRuntimeExports.jsxs(DecryptClickContext.Provider, { value: decryptValue, children: [visibleBasicAttributes.length > 0 && jsxRuntimeExports.jsxs("
|
|
2324
|
+
return jsxRuntimeExports.jsx(ContextCardProvider, { children: jsxRuntimeExports.jsx(RunClickContext.Provider, { value: onRunClick, children: jsxRuntimeExports.jsx(StreamClickContext.Provider, { value: onStreamClick, children: jsxRuntimeExports.jsxs(DecryptClickContext.Provider, { value: decryptValue, children: [visibleBasicAttributes.length > 0 && jsxRuntimeExports.jsxs(CollapsibleRoot, { defaultOpen: true, children: [jsxRuntimeExports.jsx(CollapsibleTrigger, { children: "Metadata" }), jsxRuntimeExports.jsx(CollapsibleContent, { className: "mt-0 mb-2", children: jsxRuntimeExports.jsxs("div", { className: "flex flex-col", children: [orderedBasicAttributes.map((attribute) => {
|
|
2286
2325
|
var _a;
|
|
2287
2326
|
const displayValue = (_a = attributeToDisplayFn[attribute]) == null ? void 0 : _a.call(attributeToDisplayFn, displayData[attribute]);
|
|
2288
2327
|
const isCopyableBasicAttribute = copyableBasicAttributes.has(attribute) && typeof displayValue === "string";
|
|
2289
|
-
|
|
2290
|
-
|
|
2328
|
+
const label = getAttributeDisplayName(attribute);
|
|
2329
|
+
return jsxRuntimeExports.jsx(DetailMonoKeyValueRow, { label, value: displayValue, copyText: isCopyableBasicAttribute ? displayValue : void 0 }, attribute);
|
|
2330
|
+
}), isLoading && resource === "sleep" && !displayData.resumeAt && jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-3 py-0.5", children: [jsxRuntimeExports.jsx("span", { className: "text-label-13 text-gray-900", children: "Resume" }), jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-[55%]" })] })] }) })] }), error ? jsxRuntimeExports.jsx(ErrorCard, { title: "Failed to load resource details", details: error.message, className: "my-4" }) : hasExpired ? jsxRuntimeExports.jsx(ExpiredDataMessage, {}) : resolvedAttributes.length > 0 ? resolvedAttributes.map((attribute) => jsxRuntimeExports.jsx(AttributeBlock, { isLoading, attribute, value: displayData[attribute], context: displayContext }, attribute)) : null] }) }) }) });
|
|
2291
2331
|
};
|
|
2292
2332
|
const ERROR_EVENT_TYPES = /* @__PURE__ */ new Set(["step_failed", "step_retrying"]);
|
|
2293
2333
|
const DATA_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
@@ -2369,17 +2409,17 @@ function EventItem({ event, onLoadEventData, encryptionKey, showSeparateEventOcc
|
|
|
2369
2409
|
second: "numeric"
|
|
2370
2410
|
});
|
|
2371
2411
|
const displayPayload = isLoading ? loadedData : mergedDisplay;
|
|
2372
|
-
return jsxRuntimeExports.jsxs(
|
|
2412
|
+
return jsxRuntimeExports.jsxs(CollapsibleRoot, { variant: "card", onOpenChange: canHaveData ? (open) => {
|
|
2373
2413
|
if (open)
|
|
2374
2414
|
handleExpand();
|
|
2375
|
-
} : void 0, children: [jsxRuntimeExports.jsxs("div", { className: "flex flex-col bg-background-200 [&:has(+_*)]:border-b [&:has(+_*)]:border-gray-alpha-400", children: [showSeparateEventOccurrenceTimestamps && occurredAt && jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 py-2 px-3", children: [jsxRuntimeExports.jsx("span", { className: "text-label-12 text-gray-900", children: "Occurred" }), jsxRuntimeExports.jsx(TimestampTooltip, { date: occurredAt, children: jsxRuntimeExports.jsx("span", { className: "max-w-[70%] truncate text-right text-label-12 font-mono", children: formatEventTimestamp(occurredAt) }) })] }), jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 py-2 px-3", children: [jsxRuntimeExports.jsx("span", { className: "text-label-12 text-gray-900", children: "Event ID" }), jsxRuntimeExports.jsx("span", { className: "max-w-[70%] truncate text-right text-label-12 font-mono", children: event.eventId })] }), event.correlationId && jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 py-2 px-3", children: [jsxRuntimeExports.jsx("span", { className: "text-label-12 text-gray-900", children: "Correlation ID" }), jsxRuntimeExports.jsx("span", { className: "max-w-[70%] truncate text-right text-label-12 font-mono", children: event.correlationId })] })] }), isLoading && jsxRuntimeExports.jsxs("div", { className: "p-3", children: [jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-[35%]" }), jsxRuntimeExports.jsx(Skeleton, { className: "mt-2 h-4 w-[90%]" }), jsxRuntimeExports.jsx(Skeleton, { className: "mt-2 h-4 w-[75%]" })] }), loadError && jsxRuntimeExports.jsx(ErrorCard, { title: "Failed to load event data", details: loadError, className: "mt-2" }), displayPayload != null && jsxRuntimeExports.jsx("div", { className: "[&>div]:border-none [&>div]:rounded-none", children: jsxRuntimeExports.jsx(EventDataBlock, { eventType: event.eventType, data: displayPayload }) })] });
|
|
2415
|
+
} : void 0, children: [jsxRuntimeExports.jsx(CollapsibleTrigger, { className: "px-3 py-2", children: jsxRuntimeExports.jsxs("div", { className: "flex w-full items-center justify-between gap-3", children: [jsxRuntimeExports.jsx("span", { className: "text-gray-1000 text-label-12 font-mono", children: event.eventType }), jsxRuntimeExports.jsx("span", { className: "shrink-0 text-label-13 text-gray-900", children: displayedCreatedAtTime })] }) }), jsxRuntimeExports.jsxs(CollapsibleContent, { children: [jsxRuntimeExports.jsxs("div", { className: "flex flex-col bg-background-200 [&:has(+_*)]:border-b [&:has(+_*)]:border-gray-alpha-400", children: [showSeparateEventOccurrenceTimestamps && occurredAt && jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 py-2 px-3", children: [jsxRuntimeExports.jsx("span", { className: "text-label-12 text-gray-900", children: "Occurred" }), jsxRuntimeExports.jsx(TimestampTooltip, { date: occurredAt, children: jsxRuntimeExports.jsx("span", { className: "max-w-[70%] truncate text-right text-label-12 font-mono", children: formatEventTimestamp(occurredAt) }) })] }), jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 py-2 px-3", children: [jsxRuntimeExports.jsx("span", { className: "text-label-12 text-gray-900", children: "Event ID" }), jsxRuntimeExports.jsx("span", { className: "max-w-[70%] truncate text-right text-label-12 font-mono", children: event.eventId })] }), event.correlationId && jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 py-2 px-3", children: [jsxRuntimeExports.jsx("span", { className: "text-label-12 text-gray-900", children: "Correlation ID" }), jsxRuntimeExports.jsx("span", { className: "max-w-[70%] truncate text-right text-label-12 font-mono", children: event.correlationId })] })] }), isLoading && jsxRuntimeExports.jsxs("div", { className: "p-3", children: [jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-[35%]" }), jsxRuntimeExports.jsx(Skeleton, { className: "mt-2 h-4 w-[90%]" }), jsxRuntimeExports.jsx(Skeleton, { className: "mt-2 h-4 w-[75%]" })] }), loadError && jsxRuntimeExports.jsx(ErrorCard, { title: "Failed to load event data", details: loadError, className: "mt-2" }), displayPayload != null && jsxRuntimeExports.jsx("div", { className: "[&>div]:border-none [&>div]:rounded-none", children: jsxRuntimeExports.jsx(EventDataBlock, { eventType: event.eventType, data: displayPayload }) })] })] });
|
|
2376
2416
|
}
|
|
2377
2417
|
function hasOnlyExpiredFields(data, eventType) {
|
|
2378
2418
|
if (data === null || typeof data !== "object" || Array.isArray(data)) {
|
|
2379
2419
|
return false;
|
|
2380
2420
|
}
|
|
2381
2421
|
const record = data;
|
|
2382
|
-
const refKeys =
|
|
2422
|
+
const refKeys = getEventDataRefFields(eventType);
|
|
2383
2423
|
const presentKeys = refKeys.filter((k) => k in record);
|
|
2384
2424
|
return presentKeys.length > 0 && presentKeys.every((k) => isExpiredMarker(record[k]));
|
|
2385
2425
|
}
|
|
@@ -2412,9 +2452,9 @@ function EventsList({ events, isLoading = false, error, onLoadEventData, onStrea
|
|
|
2412
2452
|
const sortedEvents = reactExports.useMemo(() => [...events].sort((a, b) => getEffectiveEventDate(a).getTime() - getEffectiveEventDate(b).getTime()), [events]);
|
|
2413
2453
|
const hasEvents = sortedEvents.length > 0 && !error;
|
|
2414
2454
|
if (!hasEvents && !isLoading) {
|
|
2415
|
-
return jsxRuntimeExports.jsx(
|
|
2455
|
+
return jsxRuntimeExports.jsx(Collapsible, { label: "Events", disabled: true });
|
|
2416
2456
|
}
|
|
2417
|
-
return jsxRuntimeExports.jsx(RunClickContext.Provider, { value: onRunClick, children: jsxRuntimeExports.jsx(StreamClickContext.Provider, { value: onStreamClick, children: jsxRuntimeExports.jsx(
|
|
2457
|
+
return jsxRuntimeExports.jsx(RunClickContext.Provider, { value: onRunClick, children: jsxRuntimeExports.jsx(StreamClickContext.Provider, { value: onStreamClick, children: jsxRuntimeExports.jsxs(CollapsibleRoot, { defaultOpen: true, children: [jsxRuntimeExports.jsx(CollapsibleTrigger, { children: "Events" }), jsxRuntimeExports.jsx(CollapsibleContent, { className: "mb-0", children: isLoading ? jsxRuntimeExports.jsx("div", { className: "flex flex-col -mx-4", children: [0, 1, 2].map((i) => jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-3 bg-background-200 px-4 py-2", children: [jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-32 rounded" }), jsxRuntimeExports.jsx(Skeleton, { className: "h-3 w-16 rounded" })] }, i)) }) : jsxRuntimeExports.jsx("div", { className: "flex flex-col -mx-4", children: sortedEvents.map((event) => jsxRuntimeExports.jsx(EventItem, { event, onLoadEventData, encryptionKey, showSeparateEventOccurrenceTimestamps }, event.eventId)) }) })] }) }) });
|
|
2418
2458
|
}
|
|
2419
2459
|
const hasField = (value, key) => key in value;
|
|
2420
2460
|
const RESOURCES_WITH_FETCHED_DETAIL = /* @__PURE__ */ new Set(["run", "step", "sleep"]);
|
|
@@ -2781,6 +2821,257 @@ const kbdVariants = cva("inline-flex items-center justify-center rounded px-1 te
|
|
|
2781
2821
|
function Kbd({ children, className, variant, size, ...props }) {
|
|
2782
2822
|
return jsxRuntimeExports.jsx("kbd", { className: cn(kbdVariants({ variant, size, className })), ...props, children });
|
|
2783
2823
|
}
|
|
2824
|
+
const PANEL_MIN_WIDTH = 280;
|
|
2825
|
+
const PANEL_HARD_MAX_WIDTH = 1300;
|
|
2826
|
+
const PANEL_DEFAULT_WIDTH = 360;
|
|
2827
|
+
const MAIN_MIN_WIDTH = 400;
|
|
2828
|
+
const PANEL_WIDTH_STORAGE_KEY = "workflow-trace-detail-panel-width";
|
|
2829
|
+
function clamp(value, min, max) {
|
|
2830
|
+
return Math.min(Math.max(value, min), max);
|
|
2831
|
+
}
|
|
2832
|
+
function computeMaxPanelWidth(availableWidth) {
|
|
2833
|
+
if (availableWidth <= 0)
|
|
2834
|
+
return PANEL_HARD_MAX_WIDTH;
|
|
2835
|
+
return Math.min(Math.max(availableWidth - MAIN_MIN_WIDTH, 0), PANEL_HARD_MAX_WIDTH);
|
|
2836
|
+
}
|
|
2837
|
+
function clampPanelWidth(width, availableWidth) {
|
|
2838
|
+
return clamp(width, PANEL_MIN_WIDTH, computeMaxPanelWidth(availableWidth));
|
|
2839
|
+
}
|
|
2840
|
+
function readStoredPanelWidth() {
|
|
2841
|
+
if (typeof window === "undefined")
|
|
2842
|
+
return PANEL_DEFAULT_WIDTH;
|
|
2843
|
+
try {
|
|
2844
|
+
const raw = window.localStorage.getItem(PANEL_WIDTH_STORAGE_KEY);
|
|
2845
|
+
const value = raw ? Number(raw) : Number.NaN;
|
|
2846
|
+
if (!Number.isFinite(value))
|
|
2847
|
+
return PANEL_DEFAULT_WIDTH;
|
|
2848
|
+
return clamp(value, PANEL_MIN_WIDTH, PANEL_HARD_MAX_WIDTH);
|
|
2849
|
+
} catch {
|
|
2850
|
+
return PANEL_DEFAULT_WIDTH;
|
|
2851
|
+
}
|
|
2852
|
+
}
|
|
2853
|
+
function writeStoredPanelWidth(width) {
|
|
2854
|
+
if (typeof window === "undefined")
|
|
2855
|
+
return;
|
|
2856
|
+
try {
|
|
2857
|
+
window.localStorage.setItem(PANEL_WIDTH_STORAGE_KEY, String(Math.round(width)));
|
|
2858
|
+
} catch {
|
|
2859
|
+
}
|
|
2860
|
+
}
|
|
2861
|
+
function DraggableBorder({ element, position, onWidthChange, onReset, "aria-label": ariaLabel, "aria-controls": ariaControls, "aria-valuemin": ariaValueMin, "aria-valuemax": ariaValueMax, "aria-valuenow": ariaValueNow }) {
|
|
2862
|
+
const [isDragging, setIsDragging] = reactExports.useState(false);
|
|
2863
|
+
const pointerIdRef = reactExports.useRef(null);
|
|
2864
|
+
const startXRef = reactExports.useRef(0);
|
|
2865
|
+
const startWidthRef = reactExports.useRef(0);
|
|
2866
|
+
const pendingWidthRef = reactExports.useRef(0);
|
|
2867
|
+
const rafRef = reactExports.useRef(null);
|
|
2868
|
+
const movedRef = reactExports.useRef(false);
|
|
2869
|
+
const lastDragEndAtRef = reactExports.useRef(0);
|
|
2870
|
+
reactExports.useEffect(() => {
|
|
2871
|
+
return () => {
|
|
2872
|
+
if (rafRef.current)
|
|
2873
|
+
cancelAnimationFrame(rafRef.current);
|
|
2874
|
+
};
|
|
2875
|
+
}, []);
|
|
2876
|
+
reactExports.useEffect(() => {
|
|
2877
|
+
if (!isDragging)
|
|
2878
|
+
return;
|
|
2879
|
+
const previous = document.body.style.userSelect;
|
|
2880
|
+
document.body.style.userSelect = "none";
|
|
2881
|
+
return () => {
|
|
2882
|
+
document.body.style.userSelect = previous;
|
|
2883
|
+
};
|
|
2884
|
+
}, [isDragging]);
|
|
2885
|
+
const stopDrag = () => {
|
|
2886
|
+
pointerIdRef.current = null;
|
|
2887
|
+
setIsDragging(false);
|
|
2888
|
+
if (rafRef.current) {
|
|
2889
|
+
cancelAnimationFrame(rafRef.current);
|
|
2890
|
+
rafRef.current = null;
|
|
2891
|
+
if (movedRef.current)
|
|
2892
|
+
onWidthChange(pendingWidthRef.current);
|
|
2893
|
+
}
|
|
2894
|
+
if (movedRef.current) {
|
|
2895
|
+
movedRef.current = false;
|
|
2896
|
+
lastDragEndAtRef.current = performance.now();
|
|
2897
|
+
}
|
|
2898
|
+
};
|
|
2899
|
+
const handlePointerDown = (e) => {
|
|
2900
|
+
if (pointerIdRef.current !== null)
|
|
2901
|
+
return;
|
|
2902
|
+
const el = element.current;
|
|
2903
|
+
if (!el)
|
|
2904
|
+
return;
|
|
2905
|
+
if (e.pointerType === "mouse" && e.button !== 0)
|
|
2906
|
+
return;
|
|
2907
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
2908
|
+
pointerIdRef.current = e.pointerId;
|
|
2909
|
+
startXRef.current = e.clientX;
|
|
2910
|
+
startWidthRef.current = el.offsetWidth;
|
|
2911
|
+
movedRef.current = false;
|
|
2912
|
+
setIsDragging(true);
|
|
2913
|
+
};
|
|
2914
|
+
const handlePointerMove = (e) => {
|
|
2915
|
+
if (pointerIdRef.current !== e.pointerId)
|
|
2916
|
+
return;
|
|
2917
|
+
if (Math.abs(e.clientX - startXRef.current) > 4) {
|
|
2918
|
+
movedRef.current = true;
|
|
2919
|
+
}
|
|
2920
|
+
const delta = position === "left" ? startXRef.current - e.clientX : e.clientX - startXRef.current;
|
|
2921
|
+
pendingWidthRef.current = startWidthRef.current + delta;
|
|
2922
|
+
if (!rafRef.current) {
|
|
2923
|
+
rafRef.current = requestAnimationFrame(() => {
|
|
2924
|
+
rafRef.current = null;
|
|
2925
|
+
onWidthChange(pendingWidthRef.current);
|
|
2926
|
+
});
|
|
2927
|
+
}
|
|
2928
|
+
};
|
|
2929
|
+
const handlePointerEnd = (e) => {
|
|
2930
|
+
if (pointerIdRef.current !== e.pointerId)
|
|
2931
|
+
return;
|
|
2932
|
+
stopDrag();
|
|
2933
|
+
};
|
|
2934
|
+
const handleLostPointerCapture = (e) => {
|
|
2935
|
+
if (pointerIdRef.current !== null && e.pointerId !== pointerIdRef.current) {
|
|
2936
|
+
return;
|
|
2937
|
+
}
|
|
2938
|
+
stopDrag();
|
|
2939
|
+
};
|
|
2940
|
+
const handleDoubleClick = () => {
|
|
2941
|
+
if (movedRef.current || performance.now() - lastDragEndAtRef.current < 500) {
|
|
2942
|
+
return;
|
|
2943
|
+
}
|
|
2944
|
+
onReset == null ? void 0 : onReset();
|
|
2945
|
+
};
|
|
2946
|
+
const handleKeyDown = (e) => {
|
|
2947
|
+
const el = element.current;
|
|
2948
|
+
if (!el)
|
|
2949
|
+
return;
|
|
2950
|
+
const step = e.shiftKey ? 64 : 16;
|
|
2951
|
+
const grow = position === "left" ? 1 : -1;
|
|
2952
|
+
let next = null;
|
|
2953
|
+
if (e.key === "ArrowLeft") {
|
|
2954
|
+
next = el.offsetWidth + grow * step;
|
|
2955
|
+
} else if (e.key === "ArrowRight") {
|
|
2956
|
+
next = el.offsetWidth - grow * step;
|
|
2957
|
+
} else if (e.key === "Home" && ariaValueMin !== void 0) {
|
|
2958
|
+
next = ariaValueMin;
|
|
2959
|
+
} else if (e.key === "End" && ariaValueMax !== void 0) {
|
|
2960
|
+
next = ariaValueMax;
|
|
2961
|
+
}
|
|
2962
|
+
if (next === null)
|
|
2963
|
+
return;
|
|
2964
|
+
e.preventDefault();
|
|
2965
|
+
onWidthChange(next);
|
|
2966
|
+
};
|
|
2967
|
+
return jsxRuntimeExports.jsx("div", { role: "separator", "aria-orientation": "vertical", "aria-label": ariaLabel, "aria-controls": ariaControls, "aria-valuemin": ariaValueMin, "aria-valuemax": ariaValueMax, "aria-valuenow": ariaValueNow, tabIndex: 0, className: cn("group absolute inset-y-0 z-10 w-[17px] cursor-col-resize touch-none outline-none", position === "left" ? "-left-2" : "-right-2"), onPointerDown: handlePointerDown, onPointerMove: handlePointerMove, onPointerUp: handlePointerEnd, onPointerCancel: handlePointerEnd, onLostPointerCapture: handleLostPointerCapture, onDoubleClick: handleDoubleClick, onKeyDown: handleKeyDown, children: jsxRuntimeExports.jsx("span", { "aria-hidden": true, className: cn("pointer-events-none absolute inset-y-0 left-1/2 w-px -translate-x-1/2 bg-transparent transition-colors delay-75 duration-100", "group-hover:bg-gray-500 group-focus-visible:bg-[var(--ds-focus-color)]", isDragging && "bg-gray-500") }) });
|
|
2968
|
+
}
|
|
2969
|
+
function useElementWidth(ref, enabled = true) {
|
|
2970
|
+
const [width, setWidth] = reactExports.useState(0);
|
|
2971
|
+
reactExports.useLayoutEffect(() => {
|
|
2972
|
+
if (!enabled)
|
|
2973
|
+
return;
|
|
2974
|
+
const el = ref.current;
|
|
2975
|
+
if (!el)
|
|
2976
|
+
return;
|
|
2977
|
+
setWidth(Math.round(el.getBoundingClientRect().width));
|
|
2978
|
+
const observer = new ResizeObserver(([entry]) => {
|
|
2979
|
+
setWidth(Math.round((entry == null ? void 0 : entry.contentRect.width) ?? 0));
|
|
2980
|
+
});
|
|
2981
|
+
observer.observe(el);
|
|
2982
|
+
return () => observer.disconnect();
|
|
2983
|
+
}, [ref, enabled]);
|
|
2984
|
+
return width;
|
|
2985
|
+
}
|
|
2986
|
+
const DETAIL_PANEL_ID = "trace-detail-panel";
|
|
2987
|
+
function useSelectedSpanInfo() {
|
|
2988
|
+
const { activeSpan } = useActiveSpan();
|
|
2989
|
+
const sidebar = useSidebarData();
|
|
2990
|
+
return reactExports.useMemo(() => {
|
|
2991
|
+
var _a, _b;
|
|
2992
|
+
if (!activeSpan)
|
|
2993
|
+
return null;
|
|
2994
|
+
const resource = (_a = activeSpan.attributes) == null ? void 0 : _a.resource;
|
|
2995
|
+
const rawEvents = filterSpanRawEvents(sidebar.events, resource, activeSpan.spanId);
|
|
2996
|
+
return {
|
|
2997
|
+
data: (_b = activeSpan.attributes) == null ? void 0 : _b.data,
|
|
2998
|
+
resource,
|
|
2999
|
+
spanId: activeSpan.spanId,
|
|
3000
|
+
rawEvents
|
|
3001
|
+
};
|
|
3002
|
+
}, [activeSpan, sidebar]);
|
|
3003
|
+
}
|
|
3004
|
+
function TraceDetailPanel({ containerRef, onNavigateToSpan, onClose }) {
|
|
3005
|
+
const { activeSpan, activeSpanId, spans } = useActiveSpan();
|
|
3006
|
+
const sidebar = useSidebarData();
|
|
3007
|
+
const selectedSpan = useSelectedSpanInfo();
|
|
3008
|
+
const isOpen = Boolean(activeSpan);
|
|
3009
|
+
const [storedWidth, setStoredWidth] = reactExports.useState(() => readStoredPanelWidth());
|
|
3010
|
+
const containerWidth = useElementWidth(containerRef, isOpen);
|
|
3011
|
+
const asideRef = reactExports.useRef(null);
|
|
3012
|
+
const handleResize = reactExports.useCallback((next) => {
|
|
3013
|
+
const clamped = clampPanelWidth(next, containerWidth);
|
|
3014
|
+
setStoredWidth(clamped);
|
|
3015
|
+
writeStoredPanelWidth(clamped);
|
|
3016
|
+
}, [containerWidth]);
|
|
3017
|
+
const panelWidth = clampPanelWidth(storedWidth, containerWidth);
|
|
3018
|
+
const panelMaxWidth = Math.max(PANEL_MIN_WIDTH, computeMaxPanelWidth(containerWidth));
|
|
3019
|
+
const { prevSpanId, nextSpanId } = reactExports.useMemo(() => {
|
|
3020
|
+
var _a, _b;
|
|
3021
|
+
if (!activeSpanId)
|
|
3022
|
+
return { prevSpanId: null, nextSpanId: null };
|
|
3023
|
+
const i = spans.findIndex((s) => s.spanId === activeSpanId);
|
|
3024
|
+
if (i === -1)
|
|
3025
|
+
return { prevSpanId: null, nextSpanId: null };
|
|
3026
|
+
return {
|
|
3027
|
+
prevSpanId: ((_a = spans[i - 1]) == null ? void 0 : _a.spanId) ?? null,
|
|
3028
|
+
nextSpanId: ((_b = spans[i + 1]) == null ? void 0 : _b.spanId) ?? null
|
|
3029
|
+
};
|
|
3030
|
+
}, [activeSpanId, spans]);
|
|
3031
|
+
const handleSelectPrev = reactExports.useCallback(() => {
|
|
3032
|
+
if (prevSpanId)
|
|
3033
|
+
onNavigateToSpan(prevSpanId);
|
|
3034
|
+
}, [prevSpanId, onNavigateToSpan]);
|
|
3035
|
+
const handleSelectNext = reactExports.useCallback(() => {
|
|
3036
|
+
if (nextSpanId)
|
|
3037
|
+
onNavigateToSpan(nextSpanId);
|
|
3038
|
+
}, [nextSpanId, onNavigateToSpan]);
|
|
3039
|
+
reactExports.useEffect(() => {
|
|
3040
|
+
if (!isOpen)
|
|
3041
|
+
return;
|
|
3042
|
+
const onKeyDown = (e) => {
|
|
3043
|
+
if (e.key !== "j" && e.key !== "k" && e.key !== "ArrowDown" && e.key !== "ArrowUp") {
|
|
3044
|
+
return;
|
|
3045
|
+
}
|
|
3046
|
+
const target = e.target;
|
|
3047
|
+
if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement || (target == null ? void 0 : target.isContentEditable)) {
|
|
3048
|
+
return;
|
|
3049
|
+
}
|
|
3050
|
+
const targetId = e.key === "k" || e.key === "ArrowUp" ? prevSpanId : nextSpanId;
|
|
3051
|
+
if (targetId) {
|
|
3052
|
+
e.preventDefault();
|
|
3053
|
+
onNavigateToSpan(targetId);
|
|
3054
|
+
}
|
|
3055
|
+
};
|
|
3056
|
+
window.addEventListener("keydown", onKeyDown);
|
|
3057
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
3058
|
+
}, [isOpen, prevSpanId, nextSpanId, onNavigateToSpan]);
|
|
3059
|
+
const selectedSpanName = reactExports.useMemo(() => {
|
|
3060
|
+
var _a, _b;
|
|
3061
|
+
if (!(selectedSpan == null ? void 0 : selectedSpan.data))
|
|
3062
|
+
return "Details";
|
|
3063
|
+
const data = selectedSpan.data;
|
|
3064
|
+
if (selectedSpan.resource === "hook") {
|
|
3065
|
+
return data.token ?? data.hookId;
|
|
3066
|
+
}
|
|
3067
|
+
const stepName = data.stepName;
|
|
3068
|
+
const workflowName = data.workflowName;
|
|
3069
|
+
return (stepName ? (_a = parseStepName(stepName)) == null ? void 0 : _a.shortName : void 0) ?? (workflowName ? (_b = parseWorkflowName(workflowName)) == null ? void 0 : _b.shortName : void 0) ?? stepName ?? workflowName ?? data.hookId ?? "Details";
|
|
3070
|
+
}, [selectedSpan == null ? void 0 : selectedSpan.data, selectedSpan == null ? void 0 : selectedSpan.resource]);
|
|
3071
|
+
if (!activeSpan)
|
|
3072
|
+
return null;
|
|
3073
|
+
return jsxRuntimeExports.jsxs("aside", { ref: asideRef, id: DETAIL_PANEL_ID, className: "relative flex flex-col h-full max-h-full shrink-0 bg-background-100 border-l border-gray-alpha-400", style: { width: panelWidth }, children: [jsxRuntimeExports.jsx(DraggableBorder, { element: asideRef, position: "left", onWidthChange: handleResize, onReset: () => handleResize(PANEL_DEFAULT_WIDTH), "aria-label": "Resize span details panel", "aria-controls": DETAIL_PANEL_ID, "aria-valuemin": PANEL_MIN_WIDTH, "aria-valuemax": panelMaxWidth, "aria-valuenow": Math.min(Math.max(Math.round(panelWidth), PANEL_MIN_WIDTH), panelMaxWidth) }), jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 shrink-0 px-4 py-[7.5px]", children: [jsxRuntimeExports.jsx("span", { className: "text-label-14 font-medium text-gray-1000 truncate block", children: selectedSpanName }), jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-0.5 shrink-0", children: [jsxRuntimeExports.jsxs(Tooltip, { children: [jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: jsxRuntimeExports.jsx(IconButton, { "aria-label": "Navigate up", "aria-keyshortcuts": "K", onClick: handleSelectPrev, disabled: !prevSpanId, children: jsxRuntimeExports.jsx(ChevronUp, { className: "w-4 h-4" }) }) }), prevSpanId ? jsxRuntimeExports.jsxs(TooltipContent, { children: ["Navigate up", jsxRuntimeExports.jsx(Kbd, { children: "K" })] }) : null] }), jsxRuntimeExports.jsxs(Tooltip, { children: [jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: jsxRuntimeExports.jsx(IconButton, { "aria-label": "Navigate down", "aria-keyshortcuts": "J", onClick: handleSelectNext, disabled: !nextSpanId, children: jsxRuntimeExports.jsx(ChevronDown, { className: "w-4 h-4" }) }) }), nextSpanId ? jsxRuntimeExports.jsxs(TooltipContent, { children: ["Navigate down", jsxRuntimeExports.jsx(Kbd, { children: "J" })] }) : null] }), jsxRuntimeExports.jsx("div", { "aria-hidden": true, className: "w-px h-4 bg-gray-alpha-400 mx-1" }), jsxRuntimeExports.jsx(IconButton, { "aria-label": "Close span details", "aria-keyshortcuts": "Escape", onClick: onClose, children: jsxRuntimeExports.jsx(X, { className: "w-4 h-4" }) })] })] }), jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-y-auto", children: jsxRuntimeExports.jsx(ErrorBoundary, { children: jsxRuntimeExports.jsx(EntityDetailPanel, { run: sidebar.run, onStreamClick: sidebar.onStreamClick, onRunClick: sidebar.onRunClick, fetchSpanDetail: sidebar.fetchSpanDetail, onWakeUpSleep: sidebar.onWakeUpSleep, onLoadEventData: sidebar.onLoadEventData, onResolveHook: sidebar.onResolveHook, encryptionKey: sidebar.encryptionKey, onDecrypt: sidebar.onDecrypt, isDecrypting: sidebar.isDecrypting, selectedSpan, showSeparateEventOccurrenceTimestamps: sidebar.showSeparateEventOccurrenceTimestamps }) }) })] });
|
|
3074
|
+
}
|
|
2784
3075
|
const WorkflowIcon = () => {
|
|
2785
3076
|
return jsxRuntimeExports.jsx("svg", { "data-testid": "geist-icon", height: "16", strokeLinejoin: "round", style: { color: "currentColor" }, viewBox: "0 0 16 16", width: "16", children: jsxRuntimeExports.jsx("path", { d: "M5.75 7L6.4209 7.33594L4.85254 10.4717C5.38789 10.771 5.75 11.3431 5.75 12V14C5.75 14.9665 4.96648 15.75 4 15.75H2C1.03352 15.75 0.25 14.9665 0.25 14V12C0.25 11.0335 1.03352 10.25 2 10.25H3.28711L5.0791 6.66504L5.75 7ZM14 10.25C14.9665 10.25 15.75 11.0335 15.75 12V14C15.75 14.9665 14.9665 15.75 14 15.75H12C11.1185 15.75 10.3909 15.098 10.2695 14.25H7V12.75H10.25V12C10.25 11.0335 11.0335 10.25 12 10.25H14ZM2 11.75C1.86192 11.75 1.75 11.8619 1.75 12V14C1.75 14.1381 1.86192 14.25 2 14.25H4C4.13808 14.25 4.25 14.1381 4.25 14V12C4.25 11.8619 4.13808 11.75 4 11.75H2ZM12 11.75C11.8619 11.75 11.75 11.8619 11.75 12V14C11.75 14.1381 11.8619 14.25 12 14.25H14C14.1381 14.25 14.25 14.1381 14.25 14V12C14.25 11.8619 14.1381 11.75 14 11.75H12ZM9 0.25C9.96649 0.25 10.75 1.03351 10.75 2V4C10.75 4.44642 10.5808 4.85197 10.3057 5.16113L12.2041 8.6416L10.8877 9.36035L8.91895 5.75H7C6.03351 5.75 5.25 4.96649 5.25 4V2C5.25 1.03351 6.03351 0.25 7 0.25H9ZM7 1.75C6.86193 1.75 6.75 1.86193 6.75 2V4C6.75 4.13807 6.86193 4.25 7 4.25H9C9.13807 4.25 9.25 4.13807 9.25 4V2C9.25 1.86193 9.13807 1.75 9 1.75H7Z", fill: "currentColor" }) });
|
|
2786
3077
|
};
|
|
@@ -2827,22 +3118,20 @@ const EventList = ({ spans, activeSpanId, searchResult, onSelectSpan }) => {
|
|
|
2827
3118
|
paddingBottom: (spans.length - end) * ROW_HEIGHT_PX
|
|
2828
3119
|
}, children: spans.slice(start, end).map((span) => jsxRuntimeExports.jsx(EventRow, { span, isSelected: span.spanId === activeSpanId, isDimmed: isSpanDimmedBySearch(span.spanId, searchResult), onSelectSpan }, span.spanId)) });
|
|
2829
3120
|
};
|
|
2830
|
-
|
|
2831
|
-
const MIN_PX = 50;
|
|
2832
|
-
const DEFAULT_START_PX = 340;
|
|
2833
|
-
function SplitPane({ children, className, defaultStartWidth = DEFAULT_START_PX, startHeader, endHeader, scrollContainerRef }) {
|
|
3121
|
+
function SplitPane({ children, className, startHeader, endHeader, scrollContainerRef }) {
|
|
2834
3122
|
const parts = reactExports.Children.toArray(children);
|
|
2835
3123
|
if (parts.length !== 2) {
|
|
2836
3124
|
throw new Error("SplitPane expects exactly two children");
|
|
2837
3125
|
}
|
|
2838
3126
|
const [start, end] = parts;
|
|
2839
|
-
const [startPx, setStartPx] = reactExports.useState(
|
|
3127
|
+
const [startPx, setStartPx] = reactExports.useState(DEFAULT_START_PX);
|
|
2840
3128
|
const [isDragging, setIsDragging] = reactExports.useState(false);
|
|
2841
3129
|
const containerRef = reactExports.useRef(null);
|
|
2842
3130
|
const gutterRef = reactExports.useRef(null);
|
|
2843
3131
|
const rafRef = reactExports.useRef(null);
|
|
2844
|
-
const pendingPx = reactExports.useRef(
|
|
3132
|
+
const pendingPx = reactExports.useRef(DEFAULT_START_PX);
|
|
2845
3133
|
const pointerIdRef = reactExports.useRef(null);
|
|
3134
|
+
const containerWidth = useElementWidth(containerRef);
|
|
2846
3135
|
reactExports.useEffect(() => {
|
|
2847
3136
|
return () => {
|
|
2848
3137
|
if (rafRef.current)
|
|
@@ -2916,13 +3205,10 @@ function SplitPane({ children, className, defaultStartWidth = DEFAULT_START_PX,
|
|
|
2916
3205
|
rafRef.current = null;
|
|
2917
3206
|
}
|
|
2918
3207
|
};
|
|
2919
|
-
const
|
|
2920
|
-
const
|
|
3208
|
+
const effectiveStartPx = containerWidth > 0 ? Math.max(MIN_PX, Math.min(containerWidth - MIN_PX - GUTTER_PX, startPx)) : startPx;
|
|
3209
|
+
const colTemplate = paneColTemplate(effectiveStartPx);
|
|
2921
3210
|
const gutter = jsxRuntimeExports.jsx("div", { ref: gutterRef, className: "relative z-20 isolate flex shrink-0 cursor-col-resize justify-center", onPointerDown: handlePointerDown, onLostPointerCapture: handleLostPointerCapture, children: jsxRuntimeExports.jsx("span", { className: "pointer-events-none relative z-10 h-full w-px shrink-0 bg-gray-alpha-400", "aria-hidden": true }) });
|
|
2922
|
-
|
|
2923
|
-
return jsxRuntimeExports.jsxs("div", { className: cn("flex flex-col h-full min-h-0", className), children: [jsxRuntimeExports.jsxs("div", { className: "shrink-0 grid", style: { gridTemplateColumns: colTemplate }, children: [jsxRuntimeExports.jsx("div", { children: startHeader }), jsxRuntimeExports.jsx("div", { className: "flex justify-center", children: jsxRuntimeExports.jsx("span", { className: "h-full w-px bg-gray-alpha-400", "aria-hidden": true }) }), jsxRuntimeExports.jsx("div", { children: endHeader })] }), jsxRuntimeExports.jsxs("div", { ref: setContainerRef, className: cn("grid flex-1 min-h-0 overflow-x-hidden overflow-y-auto", isDragging && "select-none"), style: { gridTemplateColumns: colTemplate }, children: [start, gutter, end] })] });
|
|
2924
|
-
}
|
|
2925
|
-
return jsxRuntimeExports.jsxs("div", { ref: setContainerRef, className: cn("grid h-full min-h-0 content-start overflow-x-hidden overflow-y-auto", isDragging && "select-none", className), style: { gridTemplateColumns: colTemplate, height: "100%" }, children: [start, gutter, end] });
|
|
3211
|
+
return jsxRuntimeExports.jsxs("div", { className: cn("flex flex-col h-full min-h-0", className), children: [jsxRuntimeExports.jsxs("div", { className: "shrink-0 grid", style: { gridTemplateColumns: colTemplate }, children: [jsxRuntimeExports.jsx("div", { children: startHeader }), jsxRuntimeExports.jsx("div", { className: "flex justify-center", children: jsxRuntimeExports.jsx("span", { className: "h-full w-px bg-gray-alpha-400", "aria-hidden": true }) }), jsxRuntimeExports.jsx("div", { children: endHeader })] }), jsxRuntimeExports.jsxs("div", { ref: setContainerRef, className: cn("grid flex-1 min-h-0 overflow-x-hidden overflow-y-auto", isDragging && "select-none"), style: { gridTemplateColumns: colTemplate }, children: [start, gutter, end] })] });
|
|
2926
3212
|
}
|
|
2927
3213
|
const hint = "_hint_1dmsq_3";
|
|
2928
3214
|
const styles = {
|
|
@@ -3029,33 +3315,15 @@ function useAnimatedViewport(initial) {
|
|
|
3029
3315
|
reactExports.useEffect(() => cancel, [cancel]);
|
|
3030
3316
|
return { viewport, setViewport, animateTo };
|
|
3031
3317
|
}
|
|
3032
|
-
function useSelectedSpanInfo() {
|
|
3033
|
-
const { activeSpan } = useActiveSpan();
|
|
3034
|
-
const sidebar = useSidebarData();
|
|
3035
|
-
return reactExports.useMemo(() => {
|
|
3036
|
-
var _a, _b;
|
|
3037
|
-
if (!activeSpan)
|
|
3038
|
-
return null;
|
|
3039
|
-
const resource = (_a = activeSpan.attributes) == null ? void 0 : _a.resource;
|
|
3040
|
-
const rawEvents = filterSpanRawEvents(sidebar.events, resource, activeSpan.spanId);
|
|
3041
|
-
return {
|
|
3042
|
-
data: (_b = activeSpan.attributes) == null ? void 0 : _b.data,
|
|
3043
|
-
resource,
|
|
3044
|
-
spanId: activeSpan.spanId,
|
|
3045
|
-
rawEvents
|
|
3046
|
-
};
|
|
3047
|
-
}, [activeSpan, sidebar]);
|
|
3048
|
-
}
|
|
3049
3318
|
function NewTraceViewer$1({ trace, onLoadMore, hasMore, isLoadingMore }) {
|
|
3050
3319
|
return jsxRuntimeExports.jsx(TooltipProvider, { delayDuration: 300, children: jsxRuntimeExports.jsx(ActiveSpanProvider, { spans: trace.spans, children: jsxRuntimeExports.jsx(NewTraceViewerContent, { trace, onLoadMore, hasMore, isLoadingMore }) }) });
|
|
3051
3320
|
}
|
|
3052
3321
|
function NewTraceViewerContent({ trace, onLoadMore, hasMore, isLoadingMore }) {
|
|
3053
|
-
const {
|
|
3054
|
-
const sidebar = useSidebarData();
|
|
3055
|
-
const selectedSpan = useSelectedSpanInfo();
|
|
3322
|
+
const { activeSpanId, setActiveSpan, clearActiveSpan } = useActiveSpan();
|
|
3056
3323
|
const reducedMotion = useReducedMotion();
|
|
3057
3324
|
const [searchQuery, setSearchQuery] = reactExports.useState("");
|
|
3058
3325
|
const deferredSearchQuery = reactExports.useDeferredValue(searchQuery);
|
|
3326
|
+
const paneRootRef = reactExports.useRef(null);
|
|
3059
3327
|
const searchResult = reactExports.useMemo(() => searchSpans(trace.spans, deferredSearchQuery), [trace.spans, deferredSearchQuery]);
|
|
3060
3328
|
const root = reactExports.useMemo(() => computeRootBounds(trace.spans), [trace.spans]);
|
|
3061
3329
|
const scrollContainerRef = reactExports.useRef(null);
|
|
@@ -3136,6 +3404,8 @@ function NewTraceViewerContent({ trace, onLoadMore, hasMore, isLoadingMore }) {
|
|
|
3136
3404
|
}, [setViewport, root.startTime, root.duration]);
|
|
3137
3405
|
const zoomIn = reactExports.useCallback(() => zoomBy(ZOOM_FACTOR), [zoomBy]);
|
|
3138
3406
|
const zoomOut = reactExports.useCallback(() => zoomBy(1 / ZOOM_FACTOR), [zoomBy]);
|
|
3407
|
+
const isAtMinZoom = viewDuration >= root.duration;
|
|
3408
|
+
const isAtMaxZoom = viewDuration <= MIN_VIEWPORT_MS;
|
|
3139
3409
|
const focusViewportOnSpan = reactExports.useCallback((spanId) => {
|
|
3140
3410
|
const span = trace.spans.find((s) => s.spanId === spanId);
|
|
3141
3411
|
if (!span)
|
|
@@ -3218,24 +3488,11 @@ function NewTraceViewerContent({ trace, onLoadMore, hasMore, isLoadingMore }) {
|
|
|
3218
3488
|
}, [setActiveSpan, scrollSpanIntoView, cancelPendingZoom, focusViewportOnSpan]);
|
|
3219
3489
|
const [altHeld, setAltHeld] = reactExports.useState(false);
|
|
3220
3490
|
reactExports.useEffect(() => {
|
|
3221
|
-
const handleSidebarNavKey = (e) => {
|
|
3222
|
-
const target = e.target;
|
|
3223
|
-
if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement || (target == null ? void 0 : target.isContentEditable)) {
|
|
3224
|
-
return;
|
|
3225
|
-
}
|
|
3226
|
-
const targetId = e.key === "k" ? prevSpanIdRef.current : nextSpanIdRef.current;
|
|
3227
|
-
if (targetId) {
|
|
3228
|
-
e.preventDefault();
|
|
3229
|
-
navigateToSpanRef.current(targetId);
|
|
3230
|
-
}
|
|
3231
|
-
};
|
|
3232
3491
|
const onKeyDown = (e) => {
|
|
3233
3492
|
if (e.key === "Escape") {
|
|
3234
3493
|
handleClearActiveSpan();
|
|
3235
3494
|
} else if (e.key === "Alt") {
|
|
3236
3495
|
setAltHeld(true);
|
|
3237
|
-
} else if (e.key === "j" || e.key === "k") {
|
|
3238
|
-
handleSidebarNavKey(e);
|
|
3239
3496
|
}
|
|
3240
3497
|
};
|
|
3241
3498
|
const onKeyUp = (e) => {
|
|
@@ -3341,51 +3598,13 @@ function NewTraceViewerContent({ trace, onLoadMore, hasMore, isLoadingMore }) {
|
|
|
3341
3598
|
el.addEventListener("wheel", onWheel, { passive: false });
|
|
3342
3599
|
return () => el.removeEventListener("wheel", onWheel);
|
|
3343
3600
|
}, [root.startTime, root.duration, setViewport]);
|
|
3344
|
-
|
|
3345
|
-
var _a, _b;
|
|
3346
|
-
if (!(selectedSpan == null ? void 0 : selectedSpan.data))
|
|
3347
|
-
return "Details";
|
|
3348
|
-
const data = selectedSpan.data;
|
|
3349
|
-
if (selectedSpan.resource === "hook") {
|
|
3350
|
-
return data.token ?? data.hookId;
|
|
3351
|
-
}
|
|
3352
|
-
const stepName = data.stepName;
|
|
3353
|
-
const workflowName = data.workflowName;
|
|
3354
|
-
return (stepName ? (_a = parseStepName(stepName)) == null ? void 0 : _a.shortName : void 0) ?? (workflowName ? (_b = parseWorkflowName(workflowName)) == null ? void 0 : _b.shortName : void 0) ?? stepName ?? workflowName ?? data.hookId ?? "Details";
|
|
3355
|
-
}, [selectedSpan == null ? void 0 : selectedSpan.data, selectedSpan == null ? void 0 : selectedSpan.resource]);
|
|
3356
|
-
const { prevSpanId, nextSpanId } = reactExports.useMemo(() => {
|
|
3357
|
-
var _a, _b;
|
|
3358
|
-
if (!activeSpanId)
|
|
3359
|
-
return { prevSpanId: null, nextSpanId: null };
|
|
3360
|
-
const i = trace.spans.findIndex((s) => s.spanId === activeSpanId);
|
|
3361
|
-
if (i === -1)
|
|
3362
|
-
return { prevSpanId: null, nextSpanId: null };
|
|
3363
|
-
return {
|
|
3364
|
-
prevSpanId: ((_a = trace.spans[i - 1]) == null ? void 0 : _a.spanId) ?? null,
|
|
3365
|
-
nextSpanId: ((_b = trace.spans[i + 1]) == null ? void 0 : _b.spanId) ?? null
|
|
3366
|
-
};
|
|
3367
|
-
}, [activeSpanId, trace.spans]);
|
|
3368
|
-
const handleSelectPrevSpan = reactExports.useCallback(() => {
|
|
3369
|
-
if (prevSpanId)
|
|
3370
|
-
navigateToSpan(prevSpanId);
|
|
3371
|
-
}, [prevSpanId, navigateToSpan]);
|
|
3372
|
-
const handleSelectNextSpan = reactExports.useCallback(() => {
|
|
3373
|
-
if (nextSpanId)
|
|
3374
|
-
navigateToSpan(nextSpanId);
|
|
3375
|
-
}, [nextSpanId, navigateToSpan]);
|
|
3376
|
-
const prevSpanIdRef = reactExports.useRef(prevSpanId);
|
|
3377
|
-
const nextSpanIdRef = reactExports.useRef(nextSpanId);
|
|
3378
|
-
const navigateToSpanRef = reactExports.useRef(navigateToSpan);
|
|
3379
|
-
prevSpanIdRef.current = prevSpanId;
|
|
3380
|
-
nextSpanIdRef.current = nextSpanId;
|
|
3381
|
-
navigateToSpanRef.current = navigateToSpan;
|
|
3382
|
-
return jsxRuntimeExports.jsxs("div", { "data-pane": "pane-root", "data-has-detail": activeSpan ? "" : void 0, className: "relative grid w-full h-full max-h-full grid-cols-[minmax(100px,1fr)] data-[has-detail]:grid-cols-[minmax(100px,1fr)_clamp(280px,360px,100%)]", children: [jsxRuntimeExports.jsxs("div", { id: "trace-parent", className: "grid grid-rows-[1fr] h-full min-h-0 overflow-hidden relative bg-background-100", children: [jsxRuntimeExports.jsxs(SplitPane, { scrollContainerRef, startHeader: jsxRuntimeExports.jsxs("div", { className: "bg-background-100 border-b border-gray-alpha-400 h-10 min-h-10 flex items-center pl-4 pr-2 gap-1.5", children: [jsxRuntimeExports.jsx(Search, { className: "w-3.5 h-3.5 shrink-0 text-gray-800" }), jsxRuntimeExports.jsx("input", { id: "trace-viewer-search", name: "trace-viewer-search", type: "text", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), onKeyDown: (e) => {
|
|
3601
|
+
return jsxRuntimeExports.jsxs("div", { ref: paneRootRef, "data-pane": "pane-root", className: "relative flex w-full h-full max-h-full", children: [jsxRuntimeExports.jsxs("div", { id: "trace-parent", className: "flex-1 min-w-0 grid grid-rows-[1fr] h-full min-h-0 overflow-hidden relative bg-background-100", children: [jsxRuntimeExports.jsxs(SplitPane, { scrollContainerRef, startHeader: jsxRuntimeExports.jsxs("div", { className: "bg-background-100 border-b border-gray-alpha-400 h-10 min-h-10 flex items-center pl-4 pr-2 gap-1.5", children: [jsxRuntimeExports.jsx(Search, { className: "w-3.5 h-3.5 shrink-0 text-gray-800" }), jsxRuntimeExports.jsx("input", { id: "trace-viewer-search", name: "trace-viewer-search", type: "text", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), onKeyDown: (e) => {
|
|
3383
3602
|
if (e.key === "Escape" && searchQuery) {
|
|
3384
3603
|
e.preventDefault();
|
|
3385
3604
|
e.stopPropagation();
|
|
3386
3605
|
setSearchQuery("");
|
|
3387
3606
|
}
|
|
3388
|
-
}, placeholder: "Search spans...", "aria-label": "Search spans", className: "flex-1 min-w-0 bg-transparent text-sm text-gray-1000 placeholder:text-gray-800 outline-none" }), searchQuery && jsxRuntimeExports.jsx("button", { type: "button", "aria-label": "Clear search", onClick: () => setSearchQuery(""), className: "-mr-2 hidden h-full max-w-full shrink-0 cursor-pointer items-center rounded-r-md border-0 bg-transparent px-2.5 font-inherit text-base text-gray-900 no-underline transition-colors duration-150 ease-in hover:text-gray-1000 focus-visible:-outline-offset-1 focus-visible:outline focus-visible:outline-2 focus-visible:outline-[var(--ds-focus-color)] min-[961px]:flex", children: jsxRuntimeExports.jsx(Kbd, { variant: "outline", size: "search", children: "Esc" }) })] }), endHeader: jsxRuntimeExports.jsx(TimelineHeader, { markers: timeMarkers, hoverInfo }), children: [jsxRuntimeExports.jsxs("div", { className: "block overflow-visible", children: [jsxRuntimeExports.jsx(EventList, { spans: trace.spans, activeSpanId, searchResult, onSelectSpan: handleSelectSpan }), jsxRuntimeExports.jsx("div", { ref: loadMoreSentinelRef, className: "flex justify-center", children: isLoadingMore ? jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-center gap-2 py-3 text-sm text-gray-800", children: [jsxRuntimeExports.jsx(Spinner, { size: 14 }), jsxRuntimeExports.jsx("span", { children: "Loading spans…" })] }) : null })] }), jsxRuntimeExports.jsx("div", { ref: timelineRef, className: "block min-h-0 overflow-visible relative", onDoubleClick: resetZoom, onMouseMove: handleTimelineMouseMove, onMouseLeave: handleTimelineMouseLeave, children: jsxRuntimeExports.jsx(Timeline, { spans: trace.spans, viewStart: viewport.start, viewEnd: viewport.end, markers: timeMarkers, selectedId: activeSpanId, searchResult, onSelect: handleSelectSpan, onRevealTime: handleRevealTime, hoverFraction, altHeld }) })] }), jsxRuntimeExports.jsxs("div", { className: "absolute right-3 bottom-3 z-[5] flex items-center border border-gray-alpha-400 rounded-md bg-background-100 shadow-sm overflow-hidden divide-x divide-gray-alpha-400", children: [jsxRuntimeExports.jsx(IconButton, { variant: "muted", size: "small", onClick: zoomOut, "aria-label": "Zoom out", children: jsxRuntimeExports.jsx(ZoomOut, { className: "w-4 h-4" }) }), jsxRuntimeExports.jsx(IconButton, { variant: "muted", size: "small", onClick: resetZoom, "aria-label": "Reset zoom", children: jsxRuntimeExports.jsx(RotateCcw, { className: "w-3.5 h-3.5" }) }), jsxRuntimeExports.jsx(IconButton, { variant: "muted", size: "small", onClick: zoomIn,
|
|
3607
|
+
}, placeholder: "Search spans...", "aria-label": "Search spans", className: "flex-1 min-w-0 bg-transparent text-sm text-gray-1000 placeholder:text-gray-800 outline-none" }), searchQuery && jsxRuntimeExports.jsx("button", { type: "button", "aria-label": "Clear search", onClick: () => setSearchQuery(""), className: "-mr-2 hidden h-full max-w-full shrink-0 cursor-pointer items-center rounded-r-md border-0 bg-transparent px-2.5 font-inherit text-base text-gray-900 no-underline transition-colors duration-150 ease-in hover:text-gray-1000 focus-visible:-outline-offset-1 focus-visible:outline focus-visible:outline-2 focus-visible:outline-[var(--ds-focus-color)] min-[961px]:flex", children: jsxRuntimeExports.jsx(Kbd, { variant: "outline", size: "search", children: "Esc" }) })] }), endHeader: jsxRuntimeExports.jsx(TimelineHeader, { markers: timeMarkers, hoverInfo }), children: [jsxRuntimeExports.jsxs("div", { className: "block overflow-visible", children: [jsxRuntimeExports.jsx(EventList, { spans: trace.spans, activeSpanId, searchResult, onSelectSpan: handleSelectSpan }), jsxRuntimeExports.jsx("div", { ref: loadMoreSentinelRef, className: "flex justify-center", children: isLoadingMore ? jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-center gap-2 py-3 text-sm text-gray-800", children: [jsxRuntimeExports.jsx(Spinner, { size: 14 }), jsxRuntimeExports.jsx("span", { children: "Loading spans…" })] }) : null })] }), jsxRuntimeExports.jsx("div", { ref: timelineRef, className: "block min-h-0 overflow-visible relative", onDoubleClick: resetZoom, onMouseMove: handleTimelineMouseMove, onMouseLeave: handleTimelineMouseLeave, children: jsxRuntimeExports.jsx(Timeline, { spans: trace.spans, viewStart: viewport.start, viewEnd: viewport.end, markers: timeMarkers, selectedId: activeSpanId, searchResult, onSelect: handleSelectSpan, onRevealTime: handleRevealTime, hoverFraction, altHeld }) })] }), jsxRuntimeExports.jsxs("div", { className: "absolute right-3 bottom-3 z-[5] flex items-center border border-gray-alpha-400 rounded-md bg-background-100 shadow-sm overflow-hidden divide-x divide-gray-alpha-400", children: [jsxRuntimeExports.jsx(IconButton, { variant: "muted", size: "small", onClick: zoomOut, disabled: isAtMinZoom, "aria-label": "Zoom out", children: jsxRuntimeExports.jsx(ZoomOut, { className: "w-4 h-4" }) }), jsxRuntimeExports.jsx(IconButton, { variant: "muted", size: "small", onClick: resetZoom, "aria-label": "Reset zoom", children: jsxRuntimeExports.jsx(RotateCcw, { className: "w-3.5 h-3.5" }) }), jsxRuntimeExports.jsx(IconButton, { variant: "muted", size: "small", onClick: zoomIn, disabled: isAtMaxZoom, "aria-label": "Zoom in", children: jsxRuntimeExports.jsx(ZoomIn, { className: "w-4 h-4" }) })] })] }), jsxRuntimeExports.jsx(TraceDetailPanel, { containerRef: paneRootRef, onNavigateToSpan: navigateToSpan, onClose: handleClearActiveSpan }), jsxRuntimeExports.jsx(TraceShortcutHelper, { hasMultipleSpans: trace.spans.length > 1, reducedMotion })] });
|
|
3389
3608
|
}
|
|
3390
3609
|
const NewTraceViewer = ({ run, events, sidebarData, onLoadMore, hasMore, isLoadingMore, loading = false }) => {
|
|
3391
3610
|
const trace = reactExports.useMemo(() => {
|
|
@@ -3430,7 +3649,7 @@ async function fetchResourceWithCorrelationId(env, resource, resourceId, options
|
|
|
3430
3649
|
async function fetchSpanDetailResource(env, selection, options = {}) {
|
|
3431
3650
|
const { resource, resourceId, runId } = selection;
|
|
3432
3651
|
const { encryptionKey } = options;
|
|
3433
|
-
const hydrate = async (value) =>
|
|
3652
|
+
const hydrate = async (value) => hydrateResourceIOAsync(value, encryptionKey);
|
|
3434
3653
|
if (resource === "hook") {
|
|
3435
3654
|
const result = await unwrapOrThrow(fetchHook(env, resourceId, "all"));
|
|
3436
3655
|
return hydrate(result);
|
|
@@ -3445,11 +3664,8 @@ async function fetchSpanDetailResource(env, selection, options = {}) {
|
|
|
3445
3664
|
const result = await unwrapOrThrow(
|
|
3446
3665
|
fetchEvents(env, runId, { sortOrder: "asc", limit: 1e3, withData: true })
|
|
3447
3666
|
);
|
|
3448
|
-
const allEvents = result.data.map(
|
|
3449
|
-
hydrateResourceIO
|
|
3450
|
-
);
|
|
3451
3667
|
const waitEvents = await Promise.all(
|
|
3452
|
-
|
|
3668
|
+
result.data.filter((e) => e.correlationId === resourceId).map(hydrate)
|
|
3453
3669
|
);
|
|
3454
3670
|
const data2 = waitEventsToWaitEntity(waitEvents);
|
|
3455
3671
|
if (data2 === null) {
|
|
@@ -4895,14 +5111,8 @@ function useEventsListData(env, runId, options = {}) {
|
|
|
4895
5111
|
const encryptionKeyRef = reactExports.useRef(encryptionKey);
|
|
4896
5112
|
encryptionKeyRef.current = encryptionKey;
|
|
4897
5113
|
const hydrateEvents = reactExports.useCallback(async (rawEvents) => {
|
|
4898
|
-
const hydrated = rawEvents.map(hydrateResourceIO);
|
|
4899
5114
|
const key = encryptionKeyRef.current;
|
|
4900
|
-
|
|
4901
|
-
return Promise.all(
|
|
4902
|
-
hydrated.map((ev) => hydrateResourceIOWithKey(ev, key))
|
|
4903
|
-
);
|
|
4904
|
-
}
|
|
4905
|
-
return hydrated;
|
|
5115
|
+
return Promise.all(rawEvents.map((ev) => hydrateResourceIOAsync(ev, key)));
|
|
4906
5116
|
}, []);
|
|
4907
5117
|
const fetchInitial = reactExports.useCallback(async () => {
|
|
4908
5118
|
if (isFetchingRef.current) return;
|
|
@@ -4940,7 +5150,7 @@ function useEventsListData(env, runId, options = {}) {
|
|
|
4940
5150
|
reactExports.useEffect(() => {
|
|
4941
5151
|
if (!encryptionKey || events.length === 0) return;
|
|
4942
5152
|
let cancelled = false;
|
|
4943
|
-
Promise.all(events.map((ev) =>
|
|
5153
|
+
Promise.all(events.map((ev) => hydrateResourceIOAsync(ev, encryptionKey))).then((decrypted) => {
|
|
4944
5154
|
if (!cancelled) setEvents(decrypted);
|
|
4945
5155
|
}).catch(() => {
|
|
4946
5156
|
});
|
|
@@ -5343,7 +5553,6 @@ function LiveStatus({ hasError, errorMessage }) {
|
|
|
5343
5553
|
});
|
|
5344
5554
|
function RunDetailView({
|
|
5345
5555
|
runId,
|
|
5346
|
-
// TODO: This should open the right sidebar within the trace viewer
|
|
5347
5556
|
selectedId: _selectedId
|
|
5348
5557
|
}) {
|
|
5349
5558
|
var _a;
|
|
@@ -5421,7 +5630,10 @@ function RunDetailView({
|
|
|
5421
5630
|
if (error2) {
|
|
5422
5631
|
throw error2;
|
|
5423
5632
|
}
|
|
5424
|
-
const fullEvent =
|
|
5633
|
+
const fullEvent = await hydrateResourceIOAsync(
|
|
5634
|
+
result,
|
|
5635
|
+
encryptionKeyRef.current ?? void 0
|
|
5636
|
+
);
|
|
5425
5637
|
if ("eventData" in fullEvent) {
|
|
5426
5638
|
return fullEvent.eventData;
|
|
5427
5639
|
}
|
|
@@ -5437,7 +5649,10 @@ function RunDetailView({
|
|
|
5437
5649
|
if (error2) {
|
|
5438
5650
|
throw error2;
|
|
5439
5651
|
}
|
|
5440
|
-
const fullEvent =
|
|
5652
|
+
const fullEvent = await hydrateResourceIOAsync(
|
|
5653
|
+
result,
|
|
5654
|
+
encryptionKeyRef.current ?? void 0
|
|
5655
|
+
);
|
|
5441
5656
|
if ("eventData" in fullEvent) {
|
|
5442
5657
|
return fullEvent.eventData;
|
|
5443
5658
|
}
|