@workflow/web 5.0.0-beta.23 → 5.0.0-beta.25
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/{highlighted-body-B3W2YXNL-pQbU-Oll.js → highlighted-body-B3W2YXNL-QrddlyZu.js} +1 -1
- package/build/client/assets/{home-Dz43xne_.js → home-BNApVOct.js} +2 -2
- package/build/client/assets/{manifest-608c3c54.js → manifest-379f050f.js} +1 -1
- package/build/client/assets/{mermaid-3ZIDBTTL-C_xy8SxZ.js → mermaid-3ZIDBTTL-Cg-Mp5Kj.js} +218 -100
- package/build/client/assets/{root-BlFmfRST.js → root-BsPxYsbK.js} +1 -1
- package/build/client/assets/root-F_dqJDC7.css +1 -0
- package/build/client/assets/{run-detail-C34zz02I.js → run-detail-sr7StYc6.js} +354 -331
- package/build/client/assets/server-build-DVBDkRDS.css +1 -0
- package/build/client/assets/{workflow-graph-viewer-BlDVZ5AU.js → workflow-graph-viewer-CcCwLmnF.js} +1 -1
- package/build/client/assets/{zstd-browser-decoder-Biv4GTD9.js → zstd-browser-decoder-OOeWOMJw.js} +1 -1
- package/build/server/assets/{app-BgELNM37.js → app-e2FYIgWU.js} +5 -1
- package/build/server/assets/{highlighted-body-B3W2YXNL-CP60Gm_l.js → highlighted-body-B3W2YXNL-B7xcG7gl.js} +6 -2
- package/build/server/assets/{index-D7poz6vJ.js → index-BELZxbAO.js} +7 -3
- package/build/server/assets/{index-C7C6cDW5.js → index-BafExO0s.js} +4 -0
- package/build/server/assets/{index-B8YoYr9f.js → index-DIXsjgfZ.js} +4 -0
- package/build/server/assets/{index-meg9qk8y.js → index-Dq5jTBN4.js} +4 -0
- package/build/server/assets/{mermaid-3ZIDBTTL-PK-HMOJq.js → mermaid-3ZIDBTTL-DQqBhQ9Y.js} +6 -2
- package/build/server/assets/{server-build-DAfWosK8.js → server-build-D7EgG_DH.js} +745 -510
- package/build/server/assets/{token-BCYgRbLT.js → token-guLCf66r.js} +6 -2
- package/build/server/assets/{token-util-M95T0pVo.js → token-util-CCeU4-vR.js} +6 -2
- package/build/server/assets/{zstd-browser-decoder-eXH_mKQG.js → zstd-browser-decoder-CcinVfMP.js} +7 -3
- package/build/server/index.js +5 -1
- package/package.json +5 -5
- package/build/client/assets/root-61NXpLSs.css +0 -1
- package/build/client/assets/server-build-B8TvrR_Z.css +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
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 { q as Check, O as Copy, j as ChevronRight, o as ChevronDown, C as CircleAlert, Q as parseStepName, B as parseWorkflowName, U as ErrorCard, V as format, Z as Zap, S as Send, R as ResolveHookModal, Y as Circle, X, p as ChevronUp, N as ErrorBoundary,
|
|
3
|
-
import { c as createLucideIcon, O as cn, U as DataInspector, W as DecryptClickContext, X as Button, Y as Spinner, Z as Lock, $ as RESERVED_ATTRIBUTE_KEY_PREFIX, a0 as ContextCardProvider, h as useToast, a1 as Skeleton, a2 as Yr, a3 as isEncryptedMarker, a4 as TimestampTooltip, a5 as formatDuration, a6 as _r, a7 as RunClickContext, a8 as StreamClickContext, a9 as isExpiredMarker, aa as isDoStreamStep, ab as extractConversation, ac as hasEncryptedFields, ad as EVENT_DATA_REF_FIELDS, ae as useSidebarDataOptional, af as clsx, I as cva, ag as useRowWindow, ah as isSpanDimmedBySearch, ai as ROW_HEIGHT_PX, aj as getSpanDurationMs, ak as formatDurationPrecise, al as TooltipProvider, am as ActiveSpanProvider, an as useActiveSpan, ao as useSidebarData, ap as useReducedMotion, aq as searchSpans, ar as computeRootBounds, as as computeTimeMarkers, at as getHighResInMs, au as scrollRowIntoView, av as TIMELINE_PADDING_PX, aw as Timeline, ax as TimelineHeader, ay as IconButton, az as Tooltip, aA as TooltipTrigger, aB as TooltipContent, aC as SidebarDataProvider, aD as
|
|
2
|
+
import { q as Check, O as Copy, j as ChevronRight, o as ChevronDown, C as CircleAlert, Q as parseStepName, B as parseWorkflowName, U as ErrorCard, V as format, Z as Zap, S as Send, R as ResolveHookModal, Y as Circle, X, p as ChevronUp, N as ErrorBoundary, u as unwrapOrThrow, W as WorkflowWebAPIError, I as unwrapServerActionResult, _ as useEscapeKeydown, t as composeEventHandlers, $ as useCallbackRef, a0 as useLayoutEffect2, s as useControllableState, a1 as useId, a2 as createContext2, v as Presence, x as createContextScope, l as hideOthers, m as ReactRemoveScroll, a3 as useFocusGuards, a4 as LAYOUT, a5 as wakeUpRun, r as resumeHook, A as Alert, c as AlertTitle, d as AlertDescription, a as Skeleton$1, a6 as RunActionsButtons, F as StatusBadge, e as CopyableText, b as RelativeTime, T as Tabs, K as TabsList, L as TabsTrigger, M as TabsContent, y as cancelRun, a7 as recreateRun } from "./workflow-graph-viewer-CcCwLmnF.js";
|
|
3
|
+
import { c as createLucideIcon, O as cn, U as DataInspector, W as DecryptClickContext, X as Button, Y as Spinner, Z as Lock, $ as RESERVED_ATTRIBUTE_KEY_PREFIX, a0 as ContextCardProvider, h as useToast, a1 as Skeleton, a2 as Yr, a3 as isEncryptedMarker, a4 as TimestampTooltip, a5 as formatDuration, a6 as _r, a7 as RunClickContext, a8 as StreamClickContext, a9 as isExpiredMarker, aa as isDoStreamStep, ab as extractConversation, ac as hasEncryptedFields, ad as EVENT_DATA_REF_FIELDS, ae as useSidebarDataOptional, af as clsx, I as cva, ag as useRowWindow, ah as isSpanDimmedBySearch, ai as ROW_HEIGHT_PX, aj as getSpanDurationMs, ak as formatDurationPrecise, al as TooltipProvider, am as ActiveSpanProvider, an as useActiveSpan, ao as useSidebarData, ap as useReducedMotion, aq as searchSpans, ar as computeRootBounds, as as computeTimeMarkers, at as getHighResInMs, au as scrollRowIntoView, av as TIMELINE_PADDING_PX, aw as Timeline, ax as TimelineHeader, ay as IconButton, az as Tooltip, aA as TooltipTrigger, aB as TooltipContent, aC as SidebarDataProvider, aD as fetchHook, l as fetchEvents, aE as hydrateResourceIO, aF as hydrateResourceIOWithKey, H as fetchRun, aG as fetchStep, aH as fetchStreams, aI as Slot, G as useComposedRefs, aJ as Slottable, e as cn$1, aK as buttonVariants, aL as fetchEvent, aM as fetchEventsByCorrelationId, aN as isEncryptedData, aO as hydrateData, aP as getWebRevivers, T as Tooltip$1, a as TooltipTrigger$1, b as TooltipContent$1, aQ as LIVE_UPDATE_INTERVAL_MS$1, u as useServerConfig, aR as getEncryptionKeyForRun, t as toast, L as LoaderCircle, aS as StreamViewer } from "./mermaid-3ZIDBTTL-Cg-Mp5Kj.js";
|
|
4
4
|
import { decrypt, importKey } from "./encryption-g14N5vQl.js";
|
|
5
5
|
import "./index-B6-SzLmT.js";
|
|
6
6
|
/**
|
|
@@ -327,6 +327,18 @@ function formatEventTime(date) {
|
|
|
327
327
|
hour12: false
|
|
328
328
|
}) + "." + date.getMilliseconds().toString().padStart(3, "0");
|
|
329
329
|
}
|
|
330
|
+
function parseEventDate(value) {
|
|
331
|
+
if (value == null)
|
|
332
|
+
return null;
|
|
333
|
+
const date = value instanceof Date ? value : new Date(String(value));
|
|
334
|
+
return Number.isNaN(date.getTime()) ? null : date;
|
|
335
|
+
}
|
|
336
|
+
function getEffectiveEventDate$1(event) {
|
|
337
|
+
return parseEventDate(event.occurredAt) ?? new Date(event.createdAt);
|
|
338
|
+
}
|
|
339
|
+
function getEffectiveEventTime(event) {
|
|
340
|
+
return getEffectiveEventDate$1(event).getTime();
|
|
341
|
+
}
|
|
330
342
|
function formatEventType(eventType) {
|
|
331
343
|
return eventType.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
332
344
|
}
|
|
@@ -367,13 +379,13 @@ function buildNameMaps(events, run) {
|
|
|
367
379
|
return { correlationNameMap, workflowName };
|
|
368
380
|
}
|
|
369
381
|
function buildDurationMap(events) {
|
|
370
|
-
const chronological = [...events].sort((a, b) =>
|
|
382
|
+
const chronological = [...events].sort((a, b) => getEffectiveEventTime(a) - getEffectiveEventTime(b));
|
|
371
383
|
const createdTimes = /* @__PURE__ */ new Map();
|
|
372
384
|
const firstStartedTimes = /* @__PURE__ */ new Map();
|
|
373
385
|
const startedTimes = /* @__PURE__ */ new Map();
|
|
374
386
|
const durations = /* @__PURE__ */ new Map();
|
|
375
387
|
for (const event of chronological) {
|
|
376
|
-
const ts =
|
|
388
|
+
const ts = getEffectiveEventTime(event);
|
|
377
389
|
const key = event.correlationId ?? "__run__";
|
|
378
390
|
const type = event.eventType;
|
|
379
391
|
if (type === "step_created" || type === "run_created") {
|
|
@@ -596,7 +608,7 @@ const SORT_OPTIONS = [
|
|
|
596
608
|
{ value: "desc", label: "Newest" },
|
|
597
609
|
{ value: "asc", label: "Oldest" }
|
|
598
610
|
];
|
|
599
|
-
function RowsSkeleton() {
|
|
611
|
+
function RowsSkeleton({ showSeparateEventOccurrenceTimestamps = false }) {
|
|
600
612
|
return jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-hidden", children: Array.from({ length: 16 }, (_, i) => jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-0", style: { height: 40 }, children: [jsxRuntimeExports.jsxs("div", { className: "relative flex-shrink-0 self-stretch flex items-center", style: { width: GUTTER_WIDTH }, children: [jsxRuntimeExports.jsx("div", { style: {
|
|
601
613
|
position: "absolute",
|
|
602
614
|
left: 8,
|
|
@@ -608,9 +620,9 @@ function RowsSkeleton() {
|
|
|
608
620
|
height: i % 4 === 0 ? 8 : 6,
|
|
609
621
|
borderRadius: "50%",
|
|
610
622
|
marginLeft: i % 4 === 0 ? 5 : 6
|
|
611
|
-
} })] }), jsxRuntimeExports.jsx("div", { className: "w-5 flex-shrink-0 flex items-center justify-center", children: jsxRuntimeExports.jsx(Skeleton, { className: "w-5 h-5", style: { borderRadius: 4 } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "70%" } }) }), jsxRuntimeExports.jsxs("div", { className: "min-w-0 px-4 flex items-center gap-1.5", style: { flex: "2 1 0%" }, children: [jsxRuntimeExports.jsx(Skeleton, { className: "flex-shrink-0", style: { width: 6, height: 6, borderRadius: "50%" } }), jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "60%" } })] }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "50%" } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "75%" } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "75%" } }) })] }, i)) });
|
|
623
|
+
} })] }), jsxRuntimeExports.jsx("div", { className: "w-5 flex-shrink-0 flex items-center justify-center", children: jsxRuntimeExports.jsx(Skeleton, { className: "w-5 h-5", style: { borderRadius: 4 } }) }), showSeparateEventOccurrenceTimestamps && jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "70%" } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "70%" } }) }), jsxRuntimeExports.jsxs("div", { className: "min-w-0 px-4 flex items-center gap-1.5", style: { flex: "2 1 0%" }, children: [jsxRuntimeExports.jsx(Skeleton, { className: "flex-shrink-0", style: { width: 6, height: 6, borderRadius: "50%" } }), jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "60%" } })] }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "50%" } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "75%" } }) }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "75%" } }) })] }, i)) });
|
|
612
624
|
}
|
|
613
|
-
function EventRow$1({ event, index, isFirst, isLast, isExpanded, onToggleExpand, activeGroupKey, selectedGroupKey, selectedGroupRange, correlationNameMap, workflowName, durationMap, onSelectGroup, onHoverGroup, onLoadEventData, cachedEventData, onCacheEventData, encryptionKey, onEncryptedDataDetected, suppressGroupDimming = false }) {
|
|
625
|
+
function EventRow$1({ event, index, isFirst, isLast, isExpanded, onToggleExpand, activeGroupKey, selectedGroupKey, selectedGroupRange, correlationNameMap, workflowName, durationMap, onSelectGroup, onHoverGroup, onLoadEventData, cachedEventData, onCacheEventData, encryptionKey, onEncryptedDataDetected, suppressGroupDimming = false, showSeparateEventOccurrenceTimestamps = false }) {
|
|
614
626
|
const [isLoading, setIsLoading] = reactExports.useState(false);
|
|
615
627
|
const [loadedEventData, setLoadedEventData] = reactExports.useState(cachedEventData);
|
|
616
628
|
const [loadError, setLoadError] = reactExports.useState(null);
|
|
@@ -623,6 +635,8 @@ function EventRow$1({ event, index, isFirst, isLast, isExpanded, onToggleExpand,
|
|
|
623
635
|
const rowGroupKey = isRunLevel(event.eventType) ? "__run__" : event.correlationId ?? void 0;
|
|
624
636
|
const statusDotColor = getStatusDotColor(event.eventType);
|
|
625
637
|
const createdAt = new Date(event.createdAt);
|
|
638
|
+
const occurredAt = parseEventDate(event.occurredAt);
|
|
639
|
+
const displayedCreatedAt = showSeparateEventOccurrenceTimestamps ? createdAt : getEffectiveEventDate$1(event);
|
|
626
640
|
const hasExistingEventData = "eventData" in event && event.eventData != null;
|
|
627
641
|
const isRun = isRunLevel(event.eventType);
|
|
628
642
|
const eventName = isRun ? workflowName ?? "-" : event.correlationId ? correlationNameMap.get(event.correlationId) ?? "-" : "-";
|
|
@@ -726,7 +740,7 @@ function EventRow$1({ event, index, isFirst, isLast, isExpanded, onToggleExpand,
|
|
|
726
740
|
}, children: jsxRuntimeExports.jsx(ChevronRight, { className: "h-3 w-3 transition-transform", style: {
|
|
727
741
|
color: "var(--ds-gray-900)",
|
|
728
742
|
transform: isExpanded ? "rotate(90deg)" : "rotate(0deg)"
|
|
729
|
-
} }) }), jsxRuntimeExports.jsx("div", { className: "tabular-nums min-w-0 px-4", style: { color: "var(--ds-gray-900)", flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(TimestampTooltip, { date:
|
|
743
|
+
} }) }), showSeparateEventOccurrenceTimestamps && jsxRuntimeExports.jsx("div", { className: "tabular-nums min-w-0 px-4", style: { color: "var(--ds-gray-900)", flex: "2 1 0%" }, children: occurredAt ? jsxRuntimeExports.jsx(TimestampTooltip, { date: occurredAt, children: jsxRuntimeExports.jsx("span", { children: formatEventTime(occurredAt) }) }) : "-" }), jsxRuntimeExports.jsx("div", { className: "tabular-nums min-w-0 px-4", style: { color: "var(--ds-gray-900)", flex: "2 1 0%" }, children: jsxRuntimeExports.jsx(TimestampTooltip, { date: displayedCreatedAt, children: jsxRuntimeExports.jsx("span", { children: formatEventTime(displayedCreatedAt) }) }) }), jsxRuntimeExports.jsx("div", { className: "font-medium min-w-0 px-4", style: { flex: "2 1 0%" }, children: jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5", style: { color: "var(--ds-gray-900)" }, children: [jsxRuntimeExports.jsxs("span", { style: {
|
|
730
744
|
position: "relative",
|
|
731
745
|
display: "inline-flex",
|
|
732
746
|
width: 6,
|
|
@@ -755,7 +769,7 @@ function EventRow$1({ event, index, isFirst, isLast, isExpanded, onToggleExpand,
|
|
|
755
769
|
color: "var(--ds-red-900)"
|
|
756
770
|
}, children: loadError }) : isLoading || loadedEventData === null && !hasAttemptedLoad && event.correlationId ? jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2 p-3", children: [jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "75%" } }), jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "50%" } }), jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "60%" } })] }) : jsxRuntimeExports.jsx("div", { className: "p-2 text-xs", style: { color: "var(--ds-gray-900)" }, children: "No data" })] })] })] });
|
|
757
771
|
}
|
|
758
|
-
function EventListViewInner({ events, run, onLoadEventData, hasMoreEvents = false, isLoadingMoreEvents = false, onLoadMoreEvents, encryptionKey, isLoading = false, sortOrder: sortOrderProp, onSortOrderChange, onDecrypt, isDecrypting = false, hasEncryptedData: hasEncryptedDataProp = false, onExactIdSearch }) {
|
|
772
|
+
function EventListViewInner({ events, run, onLoadEventData, hasMoreEvents = false, isLoadingMoreEvents = false, onLoadMoreEvents, encryptionKey, isLoading = false, sortOrder: sortOrderProp, onSortOrderChange, onDecrypt, isDecrypting = false, hasEncryptedData: hasEncryptedDataProp = false, onExactIdSearch, showSeparateEventOccurrenceTimestamps = false }) {
|
|
759
773
|
const toast2 = useToast();
|
|
760
774
|
const [internalSortOrder, setInternalSortOrder] = reactExports.useState("asc");
|
|
761
775
|
const effectiveSortOrder = sortOrderProp ?? internalSortOrder;
|
|
@@ -781,7 +795,7 @@ function EventListViewInner({ events, run, onLoadEventData, hasMoreEvents = fals
|
|
|
781
795
|
if (sourceEvents.length === 0)
|
|
782
796
|
return [];
|
|
783
797
|
const dir = effectiveSortOrder === "desc" ? -1 : 1;
|
|
784
|
-
return [...sourceEvents].sort((a, b) => dir * (
|
|
798
|
+
return [...sourceEvents].sort((a, b) => dir * (getEffectiveEventTime(a) - getEffectiveEventTime(b)));
|
|
785
799
|
}, [events, effectiveSortOrder, isExactSearchActive, searchResults]);
|
|
786
800
|
const hasEncryptedInlineData = reactExports.useMemo(() => {
|
|
787
801
|
const sourceEvents = isExactSearchActive ? searchResults : events;
|
|
@@ -1009,14 +1023,14 @@ function EventListViewInner({ events, run, onLoadEventData, hasMoreEvents = fals
|
|
|
1009
1023
|
borderColor: "var(--ds-gray-alpha-200)",
|
|
1010
1024
|
color: "var(--ds-gray-900)",
|
|
1011
1025
|
backgroundColor: "var(--ds-background-100)"
|
|
1012
|
-
}, children: [jsxRuntimeExports.jsx("div", { className: "flex-shrink-0", style: { width: GUTTER_WIDTH } }), jsxRuntimeExports.jsx("div", { className: "w-5 flex-shrink-0" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: "
|
|
1026
|
+
}, children: [jsxRuntimeExports.jsx("div", { className: "flex-shrink-0", style: { width: GUTTER_WIDTH } }), jsxRuntimeExports.jsx("div", { className: "w-5 flex-shrink-0" }), showSeparateEventOccurrenceTimestamps && jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: "Occurred" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: "Created" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: "Event Type" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "2 1 0%" }, children: "Name" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: "Correlation ID" }), jsxRuntimeExports.jsx("div", { className: "min-w-0 px-4", style: { flex: "3 1 0%" }, children: "Event ID" })] }), isRefetching || searchLoading ? jsxRuntimeExports.jsx(RowsSkeleton, { showSeparateEventOccurrenceTimestamps }) : sortedEvents.length === 0 ? jsxRuntimeExports.jsx("div", { className: "flex flex-1 items-center justify-center px-6 text-center text-sm", style: { color: "var(--ds-gray-700)" }, children: searchNotFound && searchQuery.trim() ? `No events found for ${searchQuery.trim()}` : searchError ? searchError : parsedSearchId && searchQuery.trim() && !onExactIdSearch ? "Exact ID search is unavailable in this view." : "No events found" }) : jsxRuntimeExports.jsx(Yr, { ref: virtuosoRef, totalCount: sortedEvents.length, overscan: 20, defaultItemHeight: 40, endReached: () => {
|
|
1013
1027
|
if (isExactSearchActive || !hasMoreEvents || isLoadingMoreEvents) {
|
|
1014
1028
|
return;
|
|
1015
1029
|
}
|
|
1016
1030
|
void (onLoadMoreEvents == null ? void 0 : onLoadMoreEvents());
|
|
1017
1031
|
}, itemContent: (index) => {
|
|
1018
1032
|
const ev = sortedEvents[index];
|
|
1019
|
-
return jsxRuntimeExports.jsx(EventRow$1, { event: ev, index, isFirst: index === 0, isLast: index === sortedEvents.length - 1, isExpanded: expandedEventIds.has(ev.eventId), onToggleExpand: toggleEventExpanded, activeGroupKey, selectedGroupKey, selectedGroupRange, correlationNameMap, workflowName, durationMap, onSelectGroup, onHoverGroup, onLoadEventData, cachedEventData: eventDataCacheRef.current.get(ev.eventId) ?? null, onCacheEventData: cacheEventData, encryptionKey, onEncryptedDataDetected: handleEncryptedDataDetected, suppressGroupDimming: isExactSearchActive });
|
|
1033
|
+
return jsxRuntimeExports.jsx(EventRow$1, { event: ev, index, isFirst: index === 0, isLast: index === sortedEvents.length - 1, isExpanded: expandedEventIds.has(ev.eventId), onToggleExpand: toggleEventExpanded, activeGroupKey, selectedGroupKey, selectedGroupRange, correlationNameMap, workflowName, durationMap, onSelectGroup, onHoverGroup, onLoadEventData, cachedEventData: eventDataCacheRef.current.get(ev.eventId) ?? null, onCacheEventData: cacheEventData, encryptionKey, onEncryptedDataDetected: handleEncryptedDataDetected, suppressGroupDimming: isExactSearchActive, showSeparateEventOccurrenceTimestamps });
|
|
1020
1034
|
}, style: { flex: 1, minHeight: 0 } }), jsxRuntimeExports.jsxs("div", { className: "relative flex-shrink-0 flex items-center h-10 border-t px-4 text-xs", style: {
|
|
1021
1035
|
borderColor: "var(--ds-gray-alpha-200)",
|
|
1022
1036
|
color: "var(--ds-gray-900)",
|
|
@@ -1026,6 +1040,22 @@ function EventListViewInner({ events, run, onLoadEventData, hasMoreEvents = fals
|
|
|
1026
1040
|
function EventListView(props) {
|
|
1027
1041
|
return jsxRuntimeExports.jsx(ContextCardProvider, { children: jsxRuntimeExports.jsx(EventListViewInner, { ...props }) });
|
|
1028
1042
|
}
|
|
1043
|
+
const COL_TEMPLATE = "340px 1px minmax(50px, 1fr)";
|
|
1044
|
+
const ROWS = [
|
|
1045
|
+
{ id: "r0", name: 62, off: 0, bar: 72 },
|
|
1046
|
+
{ id: "r1", name: 78, off: 6, bar: 48 },
|
|
1047
|
+
{ id: "r2", name: 50, off: 10, bar: 55 },
|
|
1048
|
+
{ id: "r3", name: 84, off: 18, bar: 30 },
|
|
1049
|
+
{ id: "r4", name: 45, off: 18, bar: 42 },
|
|
1050
|
+
{ id: "r5", name: 66, off: 34, bar: 38 },
|
|
1051
|
+
{ id: "r6", name: 55, off: 41, bar: 25 },
|
|
1052
|
+
{ id: "r7", name: 40, off: 50, bar: 30 }
|
|
1053
|
+
];
|
|
1054
|
+
const HEADER_MARKERS = ["m0", "m1", "m2", "m3"];
|
|
1055
|
+
const HeaderDivider = () => jsxRuntimeExports.jsx("div", { className: "flex justify-center", children: jsxRuntimeExports.jsx("span", { "aria-hidden": true, className: "h-full w-px bg-gray-alpha-400" }) });
|
|
1056
|
+
function TraceViewerSkeleton() {
|
|
1057
|
+
return jsxRuntimeExports.jsxs("output", { "aria-busy": "true", "aria-label": "Loading trace", className: "flex flex-col w-full h-full min-h-0 bg-background-100", children: [jsxRuntimeExports.jsx("span", { className: "sr-only", children: "Loading trace…" }), jsxRuntimeExports.jsxs("div", { className: "shrink-0 grid", style: { gridTemplateColumns: COL_TEMPLATE }, children: [jsxRuntimeExports.jsxs("div", { className: "h-10 min-h-10 flex items-center border-b border-gray-alpha-400 pl-4 pr-2 gap-1.5", children: [jsxRuntimeExports.jsx(Skeleton, { className: "w-3.5 h-3.5 shrink-0 rounded-sm" }), jsxRuntimeExports.jsx(Skeleton, { className: "h-3.5 w-40" })] }), jsxRuntimeExports.jsx(HeaderDivider, {}), jsxRuntimeExports.jsx("div", { className: "h-10 min-h-10 flex items-end border-b border-gray-alpha-400 px-4 pb-1 gap-2", children: jsxRuntimeExports.jsx("div", { className: "relative flex-1 flex items-end justify-between", children: HEADER_MARKERS.map((id) => jsxRuntimeExports.jsx(Skeleton, { className: "h-3.5 w-9" }, id)) }) })] }), jsxRuntimeExports.jsxs("div", { className: "grid flex-1 min-h-0 overflow-hidden", style: { gridTemplateColumns: COL_TEMPLATE }, children: [jsxRuntimeExports.jsx("div", { className: "block overflow-visible", children: jsxRuntimeExports.jsx("ul", { className: "block divide-y divide-gray-alpha-400 border-b border-gray-alpha-400", children: ROWS.map((row) => jsxRuntimeExports.jsxs("li", { className: "h-10 flex items-center pl-4 pr-2", children: [jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [jsxRuntimeExports.jsx(Skeleton, { className: "w-4 h-4 shrink-0 rounded-sm" }), jsxRuntimeExports.jsx(Skeleton, { className: "h-3.5", style: { width: `${row.name}%` } })] }), jsxRuntimeExports.jsx(Skeleton, { className: "ml-2 h-3.5 w-10 shrink-0" })] }, row.id)) }) }), jsxRuntimeExports.jsx("span", { "aria-hidden": true, className: "h-full w-px bg-gray-alpha-400" }), jsxRuntimeExports.jsx("div", { className: "relative min-h-0", children: ROWS.map((row) => jsxRuntimeExports.jsx("div", { className: "relative h-10", children: jsxRuntimeExports.jsx("div", { className: "absolute inset-x-4 inset-y-0", children: jsxRuntimeExports.jsx(Skeleton, { className: "absolute top-1/2 -translate-y-1/2 h-6 rounded-[0.25rem]", style: { left: `${row.off}%`, width: `${row.bar}%` } }) }) }, row.id)) })] })] });
|
|
1058
|
+
}
|
|
1029
1059
|
function shouldShowVerticalLine(eventType) {
|
|
1030
1060
|
if (eventType === "hook_created" || eventType === "hook_received" || eventType === "hook_disposed") {
|
|
1031
1061
|
return true;
|
|
@@ -1081,10 +1111,17 @@ const MARKER_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
|
1081
1111
|
"wait_completed",
|
|
1082
1112
|
"attr_set"
|
|
1083
1113
|
]);
|
|
1084
|
-
|
|
1114
|
+
const getEventTimestamp = (event) => {
|
|
1115
|
+
const value = (event == null ? void 0 : event.occurredAt) ?? (event == null ? void 0 : event.createdAt);
|
|
1116
|
+
if (!value)
|
|
1117
|
+
return void 0;
|
|
1118
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
1119
|
+
return Number.isNaN(date.getTime()) ? void 0 : date;
|
|
1120
|
+
};
|
|
1121
|
+
function convertEventsToSpanEvents(events, filterTypes = true, options = {}) {
|
|
1085
1122
|
return events.filter((event) => filterTypes ? MARKER_EVENT_TYPES.has(event.eventType) : true).map((event) => ({
|
|
1086
1123
|
name: event.eventType,
|
|
1087
|
-
timestamp: dateToOtelTime(event.createdAt),
|
|
1124
|
+
timestamp: dateToOtelTime(options.preferOccurredAt ? getEventTimestamp(event) ?? event.createdAt : event.createdAt),
|
|
1088
1125
|
attributes: {
|
|
1089
1126
|
eventId: event.eventId,
|
|
1090
1127
|
correlationId: event.correlationId,
|
|
@@ -1104,9 +1141,9 @@ const waitEventsToWaitEntity = (events) => {
|
|
|
1104
1141
|
return {
|
|
1105
1142
|
waitId: startEvent.correlationId,
|
|
1106
1143
|
runId: startEvent.runId,
|
|
1107
|
-
createdAt: startEvent.createdAt,
|
|
1144
|
+
createdAt: getEventTimestamp(startEvent) ?? startEvent.createdAt,
|
|
1108
1145
|
resumeAt: ((_a = startEvent.eventData) == null ? void 0 : _a.resumeAt) ? new Date(startEvent.eventData.resumeAt) : void 0,
|
|
1109
|
-
completedAt: completedEvent
|
|
1146
|
+
completedAt: getEventTimestamp(completedEvent)
|
|
1110
1147
|
};
|
|
1111
1148
|
};
|
|
1112
1149
|
function waitToSpan(events, maxEndTime, fallbackEndTime = maxEndTime) {
|
|
@@ -1163,16 +1200,16 @@ const stepEventsToStepEntity = (events) => {
|
|
|
1163
1200
|
status = "running";
|
|
1164
1201
|
attempt += 1;
|
|
1165
1202
|
if (!startedAt)
|
|
1166
|
-
startedAt = e.createdAt;
|
|
1203
|
+
startedAt = getEventTimestamp(e) ?? e.createdAt;
|
|
1167
1204
|
completedAt = void 0;
|
|
1168
1205
|
break;
|
|
1169
1206
|
case "step_completed":
|
|
1170
1207
|
status = "completed";
|
|
1171
|
-
completedAt = e.createdAt;
|
|
1208
|
+
completedAt = getEventTimestamp(e) ?? e.createdAt;
|
|
1172
1209
|
break;
|
|
1173
1210
|
case "step_failed":
|
|
1174
1211
|
status = "failed";
|
|
1175
|
-
completedAt = e.createdAt;
|
|
1212
|
+
completedAt = getEventTimestamp(e) ?? e.createdAt;
|
|
1176
1213
|
break;
|
|
1177
1214
|
case "step_retrying":
|
|
1178
1215
|
status = "pending";
|
|
@@ -1189,8 +1226,8 @@ const stepEventsToStepEntity = (events) => {
|
|
|
1189
1226
|
stepName: ((_a = createdEvent == null ? void 0 : createdEvent.eventData) == null ? void 0 : _a.stepName) ?? "",
|
|
1190
1227
|
status,
|
|
1191
1228
|
attempt,
|
|
1192
|
-
createdAt: anchorEvent.createdAt,
|
|
1193
|
-
updatedAt: (lastEvent == null ? void 0 : lastEvent.createdAt) ?? anchorEvent.createdAt,
|
|
1229
|
+
createdAt: getEventTimestamp(anchorEvent) ?? anchorEvent.createdAt,
|
|
1230
|
+
updatedAt: getEventTimestamp(lastEvent) ?? (lastEvent == null ? void 0 : lastEvent.createdAt) ?? anchorEvent.createdAt,
|
|
1194
1231
|
startedAt,
|
|
1195
1232
|
completedAt,
|
|
1196
1233
|
specVersion: anchorEvent.specVersion
|
|
@@ -1207,13 +1244,20 @@ function stepToSpan(stepEvents, maxEndTime) {
|
|
|
1207
1244
|
data: step
|
|
1208
1245
|
};
|
|
1209
1246
|
const resource = "step";
|
|
1210
|
-
const
|
|
1211
|
-
|
|
1212
|
-
|
|
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);
|
|
1213
1252
|
let activeStartTime = step.startedAt ? new Date(step.startedAt) : void 0;
|
|
1214
1253
|
const firstStartEvent = stepEvents.find((event) => event.eventType === "step_started");
|
|
1215
1254
|
if (firstStartEvent) {
|
|
1216
|
-
activeStartTime = new Date(firstStartEvent.createdAt);
|
|
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);
|
|
1217
1261
|
}
|
|
1218
1262
|
return {
|
|
1219
1263
|
spanId: String(step.stepId),
|
|
@@ -1235,7 +1279,7 @@ function stepToSpan(stepEvents, maxEndTime) {
|
|
|
1235
1279
|
};
|
|
1236
1280
|
}
|
|
1237
1281
|
const hookEventsToHookEntity = (events) => {
|
|
1238
|
-
var _a
|
|
1282
|
+
var _a;
|
|
1239
1283
|
const createdEvent = events.find((event) => event.eventType === "hook_created");
|
|
1240
1284
|
if (!createdEvent) {
|
|
1241
1285
|
return null;
|
|
@@ -1247,10 +1291,10 @@ const hookEventsToHookEntity = (events) => {
|
|
|
1247
1291
|
hookId: createdEvent.correlationId,
|
|
1248
1292
|
runId: createdEvent.runId,
|
|
1249
1293
|
token: (_a = createdEvent.eventData) == null ? void 0 : _a.token,
|
|
1250
|
-
createdAt: createdEvent.createdAt,
|
|
1294
|
+
createdAt: getEventTimestamp(createdEvent) ?? createdEvent.createdAt,
|
|
1251
1295
|
receivedCount: receivedEvents.length,
|
|
1252
|
-
lastReceivedAt: (lastReceivedEvent
|
|
1253
|
-
disposedAt: (
|
|
1296
|
+
lastReceivedAt: getEventTimestamp(lastReceivedEvent),
|
|
1297
|
+
disposedAt: getEventTimestamp(disposedEvents.at(-1))
|
|
1254
1298
|
};
|
|
1255
1299
|
};
|
|
1256
1300
|
function hookToSpan(hookEvents, maxEndTime) {
|
|
@@ -1283,15 +1327,26 @@ function hookToSpan(hookEvents, maxEndTime) {
|
|
|
1283
1327
|
function runToSpan(run, runEvents, nowTime) {
|
|
1284
1328
|
var _a;
|
|
1285
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;
|
|
1286
1337
|
const { input: _i, output: _o, error: _e, ...runIdentity } = run;
|
|
1287
1338
|
const attributes = {
|
|
1288
1339
|
resource: "run",
|
|
1289
|
-
data:
|
|
1340
|
+
data: {
|
|
1341
|
+
...runIdentity,
|
|
1342
|
+
createdAt: spanStartTime,
|
|
1343
|
+
startedAt: activeStartTime,
|
|
1344
|
+
completedAt
|
|
1345
|
+
}
|
|
1290
1346
|
};
|
|
1291
|
-
const
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
const events = convertEventsToSpanEvents(runEvents, false);
|
|
1347
|
+
const events = convertEventsToSpanEvents(runEvents, false, {
|
|
1348
|
+
preferOccurredAt: true
|
|
1349
|
+
});
|
|
1295
1350
|
return {
|
|
1296
1351
|
spanId: String(run.runId),
|
|
1297
1352
|
name: String(((_a = parseWorkflowName(run.workflowName)) == null ? void 0 : _a.shortName) ?? "?"),
|
|
@@ -1361,7 +1416,7 @@ function groupEventsByCorrelation(events) {
|
|
|
1361
1416
|
function computeLatestKnownTime(events, run) {
|
|
1362
1417
|
let latest = new Date(run.createdAt).getTime();
|
|
1363
1418
|
for (const event of events) {
|
|
1364
|
-
const t = new Date(event.createdAt).getTime();
|
|
1419
|
+
const t = (getEventTimestamp(event) ?? new Date(event.createdAt)).getTime();
|
|
1365
1420
|
if (t > latest)
|
|
1366
1421
|
latest = t;
|
|
1367
1422
|
}
|
|
@@ -1954,7 +2009,7 @@ const getModuleSpecifierFromName = (value) => {
|
|
|
1954
2009
|
}
|
|
1955
2010
|
return raw;
|
|
1956
2011
|
};
|
|
1957
|
-
const parseDateValue = (value) => {
|
|
2012
|
+
const parseDateValue$1 = (value) => {
|
|
1958
2013
|
if (value == null) {
|
|
1959
2014
|
return null;
|
|
1960
2015
|
}
|
|
@@ -1969,14 +2024,14 @@ const parseDateValue = (value) => {
|
|
|
1969
2024
|
};
|
|
1970
2025
|
const formatLocalMillisecondTime = (date) => format(date, "MMM dd HH:mm:ss.SS OO").toUpperCase();
|
|
1971
2026
|
const localMillisecondTimeOrNull = (value) => {
|
|
1972
|
-
const date = parseDateValue(value);
|
|
2027
|
+
const date = parseDateValue$1(value);
|
|
1973
2028
|
if (!date) {
|
|
1974
2029
|
return null;
|
|
1975
2030
|
}
|
|
1976
2031
|
return formatLocalMillisecondTime(date);
|
|
1977
2032
|
};
|
|
1978
2033
|
const timestampWithTooltipOrNull = (value) => {
|
|
1979
|
-
const date = parseDateValue(value);
|
|
2034
|
+
const date = parseDateValue$1(value);
|
|
1980
2035
|
if (!date)
|
|
1981
2036
|
return null;
|
|
1982
2037
|
return jsxRuntimeExports.jsx(TimestampTooltip, { date, children: jsxRuntimeExports.jsx("span", { children: formatLocalMillisecondTime(date) }) });
|
|
@@ -2183,8 +2238,8 @@ const AttributePanel = ({ data, moduleSpecifier, isLoading, error, expiredAt, on
|
|
|
2183
2238
|
return present;
|
|
2184
2239
|
if (resource === "sleep")
|
|
2185
2240
|
return present;
|
|
2186
|
-
const
|
|
2187
|
-
for (const key of
|
|
2241
|
+
const loadingPlaceholders = ["input", "output"];
|
|
2242
|
+
for (const key of loadingPlaceholders) {
|
|
2188
2243
|
if (!present.includes(key)) {
|
|
2189
2244
|
present.push(key);
|
|
2190
2245
|
}
|
|
@@ -2249,7 +2304,23 @@ const DATA_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
|
2249
2304
|
"wait_completed",
|
|
2250
2305
|
"attr_set"
|
|
2251
2306
|
]);
|
|
2252
|
-
|
|
2307
|
+
const parseDateValue = (value) => {
|
|
2308
|
+
if (value == null)
|
|
2309
|
+
return null;
|
|
2310
|
+
const date = value instanceof Date ? value : new Date(String(value));
|
|
2311
|
+
return Number.isNaN(date.getTime()) ? null : date;
|
|
2312
|
+
};
|
|
2313
|
+
const getEffectiveEventDate = (event) => parseDateValue(event.occurredAt) ?? new Date(event.createdAt);
|
|
2314
|
+
const formatEventTimestamp = (date) => date.toLocaleString(void 0, {
|
|
2315
|
+
month: "short",
|
|
2316
|
+
day: "numeric",
|
|
2317
|
+
hour: "numeric",
|
|
2318
|
+
minute: "numeric",
|
|
2319
|
+
second: "numeric",
|
|
2320
|
+
fractionalSecondDigits: 3,
|
|
2321
|
+
timeZoneName: "short"
|
|
2322
|
+
});
|
|
2323
|
+
function EventItem({ event, onLoadEventData, encryptionKey, showSeparateEventOccurrenceTimestamps = false }) {
|
|
2253
2324
|
const [loadedData, setLoadedData] = reactExports.useState(null);
|
|
2254
2325
|
const [isLoading, setIsLoading] = reactExports.useState(false);
|
|
2255
2326
|
const [loadError, setLoadError] = reactExports.useState(null);
|
|
@@ -2290,16 +2361,18 @@ function EventItem({ event, onLoadEventData, encryptionKey }) {
|
|
|
2290
2361
|
void loadEventData({ force: true });
|
|
2291
2362
|
}, [encryptionKey, loadEventData]);
|
|
2292
2363
|
const createdAt = new Date(event.createdAt);
|
|
2293
|
-
const
|
|
2364
|
+
const occurredAt = parseDateValue(event.occurredAt);
|
|
2365
|
+
const displayedCreatedAt = showSeparateEventOccurrenceTimestamps ? createdAt : getEffectiveEventDate(event);
|
|
2366
|
+
const displayedCreatedAtTime = displayedCreatedAt.toLocaleTimeString(void 0, {
|
|
2294
2367
|
hour: "numeric",
|
|
2295
2368
|
minute: "numeric",
|
|
2296
2369
|
second: "numeric"
|
|
2297
2370
|
});
|
|
2298
2371
|
const displayPayload = isLoading ? loadedData : mergedDisplay;
|
|
2299
|
-
return jsxRuntimeExports.jsxs(DetailCard, { variant: "card", summaryClassName: "px-3 py-2", summary: 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:
|
|
2372
|
+
return jsxRuntimeExports.jsxs(DetailCard, { variant: "card", summaryClassName: "px-3 py-2", summary: 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 })] }), onToggle: canHaveData ? (open) => {
|
|
2300
2373
|
if (open)
|
|
2301
2374
|
handleExpand();
|
|
2302
|
-
} : void 0, children: [jsxRuntimeExports.jsxs("div", { className: "flex flex-col bg-background-200 [&:has(+_*)]:border-b [&:has(+_*)]:border-gray-alpha-400", children: [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 }) })] });
|
|
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 }) })] });
|
|
2303
2376
|
}
|
|
2304
2377
|
function hasOnlyExpiredFields(data, eventType) {
|
|
2305
2378
|
if (data === null || typeof data !== "object" || Array.isArray(data)) {
|
|
@@ -2335,15 +2408,52 @@ function EventDataBlock({ eventType, data }) {
|
|
|
2335
2408
|
}
|
|
2336
2409
|
return jsxRuntimeExports.jsx(CopyableDataBlock, { data });
|
|
2337
2410
|
}
|
|
2338
|
-
function EventsList({ events, isLoading = false, error, onLoadEventData, onStreamClick, onRunClick, encryptionKey }) {
|
|
2339
|
-
const sortedEvents = reactExports.useMemo(() => [...events].sort((a, b) =>
|
|
2411
|
+
function EventsList({ events, isLoading = false, error, onLoadEventData, onStreamClick, onRunClick, encryptionKey, showSeparateEventOccurrenceTimestamps = false }) {
|
|
2412
|
+
const sortedEvents = reactExports.useMemo(() => [...events].sort((a, b) => getEffectiveEventDate(a).getTime() - getEffectiveEventDate(b).getTime()), [events]);
|
|
2340
2413
|
const hasEvents = sortedEvents.length > 0 && !error;
|
|
2341
2414
|
if (!hasEvents && !isLoading) {
|
|
2342
2415
|
return jsxRuntimeExports.jsx(DetailCard, { summary: "Events", disabled: true });
|
|
2343
2416
|
}
|
|
2344
|
-
return jsxRuntimeExports.jsx(RunClickContext.Provider, { value: onRunClick, children: jsxRuntimeExports.jsx(StreamClickContext.Provider, { value: onStreamClick, children: jsxRuntimeExports.jsx(DetailCard, { summary: "Events", contentClassName: "mb-0", defaultOpen: true, 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 }, event.eventId)) }) }) }) });
|
|
2417
|
+
return jsxRuntimeExports.jsx(RunClickContext.Provider, { value: onRunClick, children: jsxRuntimeExports.jsx(StreamClickContext.Provider, { value: onStreamClick, children: jsxRuntimeExports.jsx(DetailCard, { summary: "Events", contentClassName: "mb-0", defaultOpen: true, 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)) }) }) }) });
|
|
2345
2418
|
}
|
|
2346
2419
|
const hasField = (value, key) => key in value;
|
|
2420
|
+
const RESOURCES_WITH_FETCHED_DETAIL = /* @__PURE__ */ new Set(["run", "step", "sleep"]);
|
|
2421
|
+
function resourceNeedsFetchedDetail(resource) {
|
|
2422
|
+
return resource !== void 0 && RESOURCES_WITH_FETCHED_DETAIL.has(resource);
|
|
2423
|
+
}
|
|
2424
|
+
function deriveSpanDetailView(args) {
|
|
2425
|
+
const { resource, resourceId, inlineData, fetchedDetail, fetchedError } = args;
|
|
2426
|
+
const matchedDetail = spanDetailMatchesSelection(fetchedDetail, resource, resourceId) ? fetchedDetail : null;
|
|
2427
|
+
const displayData = mergeSpanDetail(inlineData, matchedDetail);
|
|
2428
|
+
if (!resource || !resourceId) {
|
|
2429
|
+
return { status: "idle", displayData, detail: null, error: void 0 };
|
|
2430
|
+
}
|
|
2431
|
+
if (fetchedError) {
|
|
2432
|
+
return {
|
|
2433
|
+
status: "error",
|
|
2434
|
+
displayData,
|
|
2435
|
+
detail: matchedDetail,
|
|
2436
|
+
error: fetchedError
|
|
2437
|
+
};
|
|
2438
|
+
}
|
|
2439
|
+
if (!resourceNeedsFetchedDetail(resource)) {
|
|
2440
|
+
return {
|
|
2441
|
+
status: "ready",
|
|
2442
|
+
displayData,
|
|
2443
|
+
detail: matchedDetail,
|
|
2444
|
+
error: void 0
|
|
2445
|
+
};
|
|
2446
|
+
}
|
|
2447
|
+
if (matchedDetail !== null) {
|
|
2448
|
+
return {
|
|
2449
|
+
status: "ready",
|
|
2450
|
+
displayData,
|
|
2451
|
+
detail: matchedDetail,
|
|
2452
|
+
error: void 0
|
|
2453
|
+
};
|
|
2454
|
+
}
|
|
2455
|
+
return { status: "loading", displayData, detail: null, error: void 0 };
|
|
2456
|
+
}
|
|
2347
2457
|
function spanDetailMatchesSelection(detail, resource, resourceId) {
|
|
2348
2458
|
if (!detail || typeof detail !== "object" || !resource || !resourceId) {
|
|
2349
2459
|
return false;
|
|
@@ -2376,16 +2486,88 @@ function mergeSpanDetail(spanData, detail) {
|
|
|
2376
2486
|
}
|
|
2377
2487
|
return merged;
|
|
2378
2488
|
}
|
|
2379
|
-
function
|
|
2380
|
-
|
|
2489
|
+
function deriveSpanSelection(selectedSpan) {
|
|
2490
|
+
if (!selectedSpan)
|
|
2491
|
+
return null;
|
|
2492
|
+
const { resource, data } = selectedSpan;
|
|
2493
|
+
if (resource === "step" && data && typeof data === "object" && "stepId" in data) {
|
|
2494
|
+
const step = data;
|
|
2495
|
+
return { resource: "step", resourceId: step.stepId, runId: step.runId };
|
|
2496
|
+
}
|
|
2497
|
+
if (resource === "run" && data && typeof data === "object" && "runId" in data) {
|
|
2498
|
+
return { resource: "run", resourceId: data.runId };
|
|
2499
|
+
}
|
|
2500
|
+
if (resource === "hook" && data && typeof data === "object" && "hookId" in data) {
|
|
2501
|
+
return { resource: "hook", resourceId: data.hookId };
|
|
2502
|
+
}
|
|
2503
|
+
if (resource === "sleep") {
|
|
2504
|
+
if (!selectedSpan.spanId)
|
|
2505
|
+
return null;
|
|
2506
|
+
const waitData = data;
|
|
2507
|
+
return {
|
|
2508
|
+
resource: "sleep",
|
|
2509
|
+
resourceId: selectedSpan.spanId,
|
|
2510
|
+
runId: waitData == null ? void 0 : waitData.runId
|
|
2511
|
+
};
|
|
2512
|
+
}
|
|
2513
|
+
return null;
|
|
2381
2514
|
}
|
|
2382
|
-
function
|
|
2383
|
-
|
|
2515
|
+
function useSelectedSpanDetail(selectedSpan, fetchSpanDetail) {
|
|
2516
|
+
const selection = reactExports.useMemo(() => deriveSpanSelection(selectedSpan), [selectedSpan]);
|
|
2517
|
+
const resource = selection == null ? void 0 : selection.resource;
|
|
2518
|
+
const resourceId = selection == null ? void 0 : selection.resourceId;
|
|
2519
|
+
const runId = selection == null ? void 0 : selection.runId;
|
|
2520
|
+
const selectionKey = resource && resourceId ? `${resource}:${resourceId}` : null;
|
|
2521
|
+
const needsFetch = resourceNeedsFetchedDetail(resource);
|
|
2522
|
+
const [fetched, setFetched] = reactExports.useState({ detail: null, error: null, errorKey: null });
|
|
2523
|
+
const tokenRef = reactExports.useRef(0);
|
|
2524
|
+
const selectionRef = reactExports.useRef(selection);
|
|
2525
|
+
selectionRef.current = selection;
|
|
2526
|
+
reactExports.useEffect(() => {
|
|
2527
|
+
if (!selectionKey || !needsFetch) {
|
|
2528
|
+
return;
|
|
2529
|
+
}
|
|
2530
|
+
const activeSelection = selectionRef.current;
|
|
2531
|
+
if (!activeSelection) {
|
|
2532
|
+
return;
|
|
2533
|
+
}
|
|
2534
|
+
const token = ++tokenRef.current;
|
|
2535
|
+
fetchSpanDetail(activeSelection).then((detail) => {
|
|
2536
|
+
if (tokenRef.current !== token)
|
|
2537
|
+
return;
|
|
2538
|
+
setFetched({ detail, error: null, errorKey: null });
|
|
2539
|
+
}).catch((err) => {
|
|
2540
|
+
if (tokenRef.current !== token)
|
|
2541
|
+
return;
|
|
2542
|
+
setFetched({
|
|
2543
|
+
detail: null,
|
|
2544
|
+
error: err instanceof Error ? err : new Error(String(err)),
|
|
2545
|
+
errorKey: selectionKey
|
|
2546
|
+
});
|
|
2547
|
+
});
|
|
2548
|
+
}, [selectionKey, runId, needsFetch, fetchSpanDetail]);
|
|
2549
|
+
const scopedError = fetched.errorKey === selectionKey ? fetched.error : null;
|
|
2550
|
+
const view = reactExports.useMemo(() => deriveSpanDetailView({
|
|
2551
|
+
resource,
|
|
2552
|
+
resourceId,
|
|
2553
|
+
inlineData: selectedSpan == null ? void 0 : selectedSpan.data,
|
|
2554
|
+
fetchedDetail: fetched.detail,
|
|
2555
|
+
fetchedError: scopedError
|
|
2556
|
+
}), [resource, resourceId, selectedSpan == null ? void 0 : selectedSpan.data, fetched.detail, scopedError]);
|
|
2557
|
+
return {
|
|
2558
|
+
status: view.status,
|
|
2559
|
+
resource,
|
|
2560
|
+
resourceId,
|
|
2561
|
+
runId,
|
|
2562
|
+
displayData: view.displayData,
|
|
2563
|
+
detail: view.detail,
|
|
2564
|
+
error: view.error
|
|
2565
|
+
};
|
|
2384
2566
|
}
|
|
2385
2567
|
function isHook(data) {
|
|
2386
2568
|
return data !== null && typeof data === "object" && "hookId" in data;
|
|
2387
2569
|
}
|
|
2388
|
-
function EntityDetailPanel({ run, onStreamClick, onRunClick,
|
|
2570
|
+
function EntityDetailPanel({ run, onStreamClick, onRunClick, fetchSpanDetail, onWakeUpSleep, onLoadEventData, onResolveHook, encryptionKey, onDecrypt, isDecrypting = false, selectedSpan, showSeparateEventOccurrenceTimestamps = false }) {
|
|
2389
2571
|
const toast2 = useToast();
|
|
2390
2572
|
const [stoppingSleep, setStoppingSleep] = reactExports.useState(false);
|
|
2391
2573
|
const [showResolveHookModal, setShowResolveHookModal] = reactExports.useState(false);
|
|
@@ -2396,41 +2578,8 @@ function EntityDetailPanel({ run, onStreamClick, onRunClick, spanDetailData, spa
|
|
|
2396
2578
|
const data = selectedSpan == null ? void 0 : selectedSpan.data;
|
|
2397
2579
|
const rawEvents = selectedSpan == null ? void 0 : selectedSpan.rawEvents;
|
|
2398
2580
|
const rawEventsLength = (rawEvents == null ? void 0 : rawEvents.length) ?? 0;
|
|
2399
|
-
const { resource, resourceId,
|
|
2400
|
-
|
|
2401
|
-
return { resource: void 0, resourceId: void 0, runId: void 0 };
|
|
2402
|
-
}
|
|
2403
|
-
const res = selectedSpan.resource;
|
|
2404
|
-
if (res === "step" && isStep(data)) {
|
|
2405
|
-
return { resource: "step", resourceId: data.stepId, runId: data.runId };
|
|
2406
|
-
}
|
|
2407
|
-
if (res === "run" && isWorkflowRun(data)) {
|
|
2408
|
-
return { resource: "run", resourceId: data.runId, runId: void 0 };
|
|
2409
|
-
}
|
|
2410
|
-
if (res === "hook" && isHook(data)) {
|
|
2411
|
-
return { resource: "hook", resourceId: data.hookId, runId: void 0 };
|
|
2412
|
-
}
|
|
2413
|
-
if (res === "sleep") {
|
|
2414
|
-
const waitData = data;
|
|
2415
|
-
return {
|
|
2416
|
-
resource: "sleep",
|
|
2417
|
-
resourceId: selectedSpan.spanId,
|
|
2418
|
-
runId: waitData == null ? void 0 : waitData.runId
|
|
2419
|
-
};
|
|
2420
|
-
}
|
|
2421
|
-
return { resource: void 0, resourceId: void 0, runId: void 0 };
|
|
2422
|
-
}, [selectedSpan, data]);
|
|
2423
|
-
const onSpanSelectRef = reactExports.useRef(onSpanSelect);
|
|
2424
|
-
onSpanSelectRef.current = onSpanSelect;
|
|
2425
|
-
reactExports.useEffect(() => {
|
|
2426
|
-
if (resource && resourceId && ["run", "step", "hook", "sleep"].includes(resource)) {
|
|
2427
|
-
onSpanSelectRef.current({
|
|
2428
|
-
resource,
|
|
2429
|
-
resourceId,
|
|
2430
|
-
runId
|
|
2431
|
-
});
|
|
2432
|
-
}
|
|
2433
|
-
}, [resource, resourceId, runId]);
|
|
2581
|
+
const { status, resource, resourceId, displayData, detail: matchedSpanDetailData, error } = useSelectedSpanDetail(selectedSpan, fetchSpanDetail);
|
|
2582
|
+
const loading = status === "loading";
|
|
2434
2583
|
const canWakeUp = reactExports.useMemo(() => {
|
|
2435
2584
|
if (resource !== "sleep" || !rawEvents)
|
|
2436
2585
|
return false;
|
|
@@ -2463,9 +2612,6 @@ function EntityDetailPanel({ run, onStreamClick, onRunClick, spanDetailData, spa
|
|
|
2463
2612
|
run.status,
|
|
2464
2613
|
resolvedHookIds
|
|
2465
2614
|
]);
|
|
2466
|
-
const error = spanDetailError ?? void 0;
|
|
2467
|
-
const loading = spanDetailLoading ?? false;
|
|
2468
|
-
const matchedSpanDetailData = reactExports.useMemo(() => spanDetailMatchesSelection(spanDetailData, resource, resourceId) ? spanDetailData : null, [spanDetailData, resource, resourceId]);
|
|
2469
2615
|
const hookToken = reactExports.useMemo(() => {
|
|
2470
2616
|
if (resource !== "hook" || !resourceId)
|
|
2471
2617
|
return void 0;
|
|
@@ -2550,7 +2696,6 @@ function EntityDetailPanel({ run, onStreamClick, onRunClick, spanDetailData, spa
|
|
|
2550
2696
|
setResolvingHook(false);
|
|
2551
2697
|
}
|
|
2552
2698
|
}, [onResolveHook, hookToken, resolvingHook, matchedSpanDetailData, data]);
|
|
2553
|
-
const displayData = reactExports.useMemo(() => mergeSpanDetail(data, matchedSpanDetailData), [data, matchedSpanDetailData]);
|
|
2554
2699
|
const moduleSpecifier = reactExports.useMemo(() => {
|
|
2555
2700
|
const displayRecord = displayData;
|
|
2556
2701
|
const displayStepName = displayRecord.stepName;
|
|
@@ -2579,43 +2724,7 @@ function EntityDetailPanel({ run, onStreamClick, onRunClick, spanDetailData, spa
|
|
|
2579
2724
|
}, children: [jsxRuntimeExports.jsx(Zap, { className: "h-4 w-4" }), stoppingSleep ? "Waking up..." : "Wake Up Sleep"] }), resource === "hook" && canResolveHook && jsxRuntimeExports.jsxs("button", { type: "button", onClick: () => setShowResolveHookModal(true), disabled: resolvingHook, className: clsx("flex items-center justify-center gap-2 rounded-md px-3 py-2 text-sm font-medium", "disabled:opacity-50 disabled:cursor-not-allowed transition-colors", resolvingHook ? "opacity-50 cursor-not-allowed" : "cursor-pointer"), style: {
|
|
2580
2725
|
background: "var(--ds-gray-1000)",
|
|
2581
2726
|
color: "var(--ds-background-100)"
|
|
2582
|
-
}, children: [jsxRuntimeExports.jsx(Send, { className: "h-4 w-4" }), "Resolve Hook"] })] })] }), jsxRuntimeExports.jsx(AttributePanel, { data: displayData, moduleSpecifier, expiredAt: run.expiredAt, isLoading: loading, error: error ?? void 0, onStreamClick, onRunClick, onDecrypt, isDecrypting, resource }), rawEvents && jsxRuntimeExports.jsx(EventsList, { events: rawEvents, onLoadEventData, onStreamClick, onRunClick, encryptionKey })] }) }), jsxRuntimeExports.jsx(ResolveHookModal, { isOpen: showResolveHookModal, onClose: () => setShowResolveHookModal(false), onSubmit: handleResolveHook, isSubmitting: resolvingHook })] });
|
|
2583
|
-
}
|
|
2584
|
-
const kbdVariants = cva("inline-flex items-center justify-center rounded px-1 text-center font-sans", {
|
|
2585
|
-
variants: {
|
|
2586
|
-
variant: {
|
|
2587
|
-
subtle: "bg-background-100/20",
|
|
2588
|
-
outline: "border border-gray-alpha-400 bg-background-100 font-medium text-gray-900"
|
|
2589
|
-
},
|
|
2590
|
-
size: {
|
|
2591
|
-
default: "h-5 min-w-5 text-xs leading-none",
|
|
2592
|
-
compact: "h-4 min-h-4 min-w-4 text-[11px] leading-none",
|
|
2593
|
-
search: "h-5 min-h-5 min-w-5 text-[13px] leading-[1.7em]"
|
|
2594
|
-
}
|
|
2595
|
-
},
|
|
2596
|
-
defaultVariants: {
|
|
2597
|
-
variant: "subtle",
|
|
2598
|
-
size: "default"
|
|
2599
|
-
}
|
|
2600
|
-
});
|
|
2601
|
-
function Kbd({ children, className, variant, size, ...props }) {
|
|
2602
|
-
return jsxRuntimeExports.jsx("kbd", { className: cn(kbdVariants({ variant, size, className })), ...props, children });
|
|
2603
|
-
}
|
|
2604
|
-
const COL_TEMPLATE = "340px 1px minmax(50px, 1fr)";
|
|
2605
|
-
const ROWS = [
|
|
2606
|
-
{ id: "r0", name: 62, off: 0, bar: 72 },
|
|
2607
|
-
{ id: "r1", name: 78, off: 6, bar: 48 },
|
|
2608
|
-
{ id: "r2", name: 50, off: 10, bar: 55 },
|
|
2609
|
-
{ id: "r3", name: 84, off: 18, bar: 30 },
|
|
2610
|
-
{ id: "r4", name: 45, off: 18, bar: 42 },
|
|
2611
|
-
{ id: "r5", name: 66, off: 34, bar: 38 },
|
|
2612
|
-
{ id: "r6", name: 55, off: 41, bar: 25 },
|
|
2613
|
-
{ id: "r7", name: 40, off: 50, bar: 30 }
|
|
2614
|
-
];
|
|
2615
|
-
const HEADER_MARKERS = ["m0", "m1", "m2", "m3"];
|
|
2616
|
-
const HeaderDivider = () => jsxRuntimeExports.jsx("div", { className: "flex justify-center", children: jsxRuntimeExports.jsx("span", { "aria-hidden": true, className: "h-full w-px bg-gray-alpha-400" }) });
|
|
2617
|
-
function TraceViewerSkeleton() {
|
|
2618
|
-
return jsxRuntimeExports.jsxs("output", { "aria-busy": "true", "aria-label": "Loading trace", className: "flex flex-col w-full h-full min-h-0 bg-background-100", children: [jsxRuntimeExports.jsx("span", { className: "sr-only", children: "Loading trace…" }), jsxRuntimeExports.jsxs("div", { className: "shrink-0 grid", style: { gridTemplateColumns: COL_TEMPLATE }, children: [jsxRuntimeExports.jsxs("div", { className: "h-10 min-h-10 flex items-center border-b border-gray-alpha-400 pl-4 pr-2 gap-1.5", children: [jsxRuntimeExports.jsx(Skeleton, { className: "w-3.5 h-3.5 shrink-0 rounded-sm" }), jsxRuntimeExports.jsx(Skeleton, { className: "h-3.5 w-40" })] }), jsxRuntimeExports.jsx(HeaderDivider, {}), jsxRuntimeExports.jsx("div", { className: "h-10 min-h-10 flex items-end border-b border-gray-alpha-400 px-4 pb-1 gap-2", children: jsxRuntimeExports.jsx("div", { className: "relative flex-1 flex items-end justify-between", children: HEADER_MARKERS.map((id) => jsxRuntimeExports.jsx(Skeleton, { className: "h-3.5 w-9" }, id)) }) })] }), jsxRuntimeExports.jsxs("div", { className: "grid flex-1 min-h-0 overflow-hidden", style: { gridTemplateColumns: COL_TEMPLATE }, children: [jsxRuntimeExports.jsx("div", { className: "block overflow-visible", children: jsxRuntimeExports.jsx("ul", { className: "block divide-y divide-gray-alpha-400 border-b border-gray-alpha-400", children: ROWS.map((row) => jsxRuntimeExports.jsxs("li", { className: "h-10 flex items-center pl-4 pr-2", children: [jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [jsxRuntimeExports.jsx(Skeleton, { className: "w-4 h-4 shrink-0 rounded-sm" }), jsxRuntimeExports.jsx(Skeleton, { className: "h-3.5", style: { width: `${row.name}%` } })] }), jsxRuntimeExports.jsx(Skeleton, { className: "ml-2 h-3.5 w-10 shrink-0" })] }, row.id)) }) }), jsxRuntimeExports.jsx("span", { "aria-hidden": true, className: "h-full w-px bg-gray-alpha-400" }), jsxRuntimeExports.jsx("div", { className: "relative min-h-0", children: ROWS.map((row) => jsxRuntimeExports.jsx("div", { className: "relative h-10", children: jsxRuntimeExports.jsx("div", { className: "absolute inset-x-4 inset-y-0", children: jsxRuntimeExports.jsx(Skeleton, { className: "absolute top-1/2 -translate-y-1/2 h-6 rounded-[0.25rem]", style: { left: `${row.off}%`, width: `${row.bar}%` } }) }) }, row.id)) })] })] });
|
|
2727
|
+
}, children: [jsxRuntimeExports.jsx(Send, { className: "h-4 w-4" }), "Resolve Hook"] })] })] }), jsxRuntimeExports.jsx(AttributePanel, { data: displayData, moduleSpecifier, expiredAt: run.expiredAt, isLoading: loading, error: error ?? void 0, onStreamClick, onRunClick, onDecrypt, isDecrypting, resource }), rawEvents && jsxRuntimeExports.jsx(EventsList, { events: rawEvents, onLoadEventData, onStreamClick, onRunClick, encryptionKey, showSeparateEventOccurrenceTimestamps })] }) }), jsxRuntimeExports.jsx(ResolveHookModal, { isOpen: showResolveHookModal, onClose: () => setShowResolveHookModal(false), onSubmit: handleResolveHook, isSubmitting: resolvingHook })] });
|
|
2619
2728
|
}
|
|
2620
2729
|
function useIntersectionObserver(elementRef, { threshold = 0, rootRef, rootMargin = "0%", freezeOnceVisible = false } = {}) {
|
|
2621
2730
|
const [entry, setEntry] = reactExports.useState();
|
|
@@ -2652,6 +2761,26 @@ function useLoadMoreOnScroll(loadMore, { hasMore, isLoadingMore, rootRef, rootMa
|
|
|
2652
2761
|
}, [entry == null ? void 0 : entry.isIntersecting, hasMore, isLoadingMore]);
|
|
2653
2762
|
return sentinelRef;
|
|
2654
2763
|
}
|
|
2764
|
+
const kbdVariants = cva("inline-flex items-center justify-center rounded px-1 text-center font-sans", {
|
|
2765
|
+
variants: {
|
|
2766
|
+
variant: {
|
|
2767
|
+
subtle: "bg-background-100/20",
|
|
2768
|
+
outline: "border border-gray-alpha-400 bg-background-100 font-medium text-gray-900"
|
|
2769
|
+
},
|
|
2770
|
+
size: {
|
|
2771
|
+
default: "h-5 min-w-5 text-xs leading-none",
|
|
2772
|
+
compact: "h-4 min-h-4 min-w-4 text-[11px] leading-none",
|
|
2773
|
+
search: "h-5 min-h-5 min-w-5 text-[13px] leading-[1.7em]"
|
|
2774
|
+
}
|
|
2775
|
+
},
|
|
2776
|
+
defaultVariants: {
|
|
2777
|
+
variant: "subtle",
|
|
2778
|
+
size: "default"
|
|
2779
|
+
}
|
|
2780
|
+
});
|
|
2781
|
+
function Kbd({ children, className, variant, size, ...props }) {
|
|
2782
|
+
return jsxRuntimeExports.jsx("kbd", { className: cn(kbdVariants({ variant, size, className })), ...props, children });
|
|
2783
|
+
}
|
|
2655
2784
|
const WorkflowIcon = () => {
|
|
2656
2785
|
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" }) });
|
|
2657
2786
|
};
|
|
@@ -2698,57 +2827,6 @@ const EventList = ({ spans, activeSpanId, searchResult, onSelectSpan }) => {
|
|
|
2698
2827
|
paddingBottom: (spans.length - end) * ROW_HEIGHT_PX
|
|
2699
2828
|
}, children: spans.slice(start, end).map((span) => jsxRuntimeExports.jsx(EventRow, { span, isSelected: span.spanId === activeSpanId, isDimmed: isSpanDimmedBySearch(span.spanId, searchResult), onSelectSpan }, span.spanId)) });
|
|
2700
2829
|
};
|
|
2701
|
-
const hint = "_hint_1dmsq_3";
|
|
2702
|
-
const styles = {
|
|
2703
|
-
hint
|
|
2704
|
-
};
|
|
2705
|
-
const DISMISSALS_KEY = "workflow-step-shortcut-helper-dismissals";
|
|
2706
|
-
const DISMISSAL_LIMIT = 3;
|
|
2707
|
-
const HINT_ROTATION_MS = 8e3;
|
|
2708
|
-
function getAltKeyLabel() {
|
|
2709
|
-
if (typeof navigator === "undefined")
|
|
2710
|
-
return "Alt";
|
|
2711
|
-
return navigator.platform.toLowerCase().includes("mac") ? "Option" : "Alt";
|
|
2712
|
-
}
|
|
2713
|
-
function readDismissals() {
|
|
2714
|
-
try {
|
|
2715
|
-
const dismissals = Number.parseInt(window.localStorage.getItem(DISMISSALS_KEY) ?? "0", 10);
|
|
2716
|
-
return Number.isNaN(dismissals) ? 0 : dismissals;
|
|
2717
|
-
} catch {
|
|
2718
|
-
return 0;
|
|
2719
|
-
}
|
|
2720
|
-
}
|
|
2721
|
-
function AltHint() {
|
|
2722
|
-
return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: ["Hold", jsxRuntimeExports.jsx(Kbd, { variant: "outline", size: "compact", className: "mx-1", children: getAltKeyLabel() }), "to see delta between spans"] });
|
|
2723
|
-
}
|
|
2724
|
-
function NavHint() {
|
|
2725
|
-
return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: ["Use", jsxRuntimeExports.jsx(Kbd, { variant: "outline", size: "compact", className: "ml-1", children: "J" }), jsxRuntimeExports.jsx("span", { className: "mx-1", children: "/" }), jsxRuntimeExports.jsx(Kbd, { variant: "outline", size: "compact", className: "mr-1", children: "K" }), "to move between spans"] });
|
|
2726
|
-
}
|
|
2727
|
-
function TraceShortcutHelper({ hasMultipleSpans, reducedMotion }) {
|
|
2728
|
-
const [visible, setVisible] = reactExports.useState(false);
|
|
2729
|
-
const [index, setIndex] = reactExports.useState(0);
|
|
2730
|
-
reactExports.useEffect(() => {
|
|
2731
|
-
setVisible(readDismissals() < DISMISSAL_LIMIT);
|
|
2732
|
-
}, []);
|
|
2733
|
-
reactExports.useEffect(() => {
|
|
2734
|
-
if (reducedMotion)
|
|
2735
|
-
return;
|
|
2736
|
-
const id = setInterval(() => {
|
|
2737
|
-
setIndex((i) => i === 0 ? 1 : 0);
|
|
2738
|
-
}, HINT_ROTATION_MS);
|
|
2739
|
-
return () => clearInterval(id);
|
|
2740
|
-
}, [reducedMotion]);
|
|
2741
|
-
if (!visible || !hasMultipleSpans)
|
|
2742
|
-
return null;
|
|
2743
|
-
const dismiss = () => {
|
|
2744
|
-
try {
|
|
2745
|
-
window.localStorage.setItem(DISMISSALS_KEY, String(readDismissals() + 1));
|
|
2746
|
-
} catch {
|
|
2747
|
-
}
|
|
2748
|
-
setVisible(false);
|
|
2749
|
-
};
|
|
2750
|
-
return jsxRuntimeExports.jsxs("div", { className: "group absolute bottom-3 left-1/2 z-10 hidden h-8 max-w-[calc(100%-2rem)] -translate-x-1/2 items-center gap-1 text-xs leading-none text-gray-900 md:inline-flex", children: [jsxRuntimeExports.jsx("span", { "aria-live": "polite", "aria-atomic": "true", className: "inline-flex items-center whitespace-nowrap", children: reducedMotion ? jsxRuntimeExports.jsx(AltHint, {}) : jsxRuntimeExports.jsx("span", { className: `inline-flex items-center ${styles.hint}`, children: index === 0 ? jsxRuntimeExports.jsx(AltHint, {}) : jsxRuntimeExports.jsx(NavHint, {}) }, index) }), jsxRuntimeExports.jsx("button", { type: "button", className: "inline-flex h-5 w-5 items-center justify-center rounded text-muted-foreground opacity-0 transition-opacity hover:bg-accent hover:text-foreground group-hover:opacity-100 focus-visible:opacity-100 motion-reduce:transition-none", onClick: dismiss, "aria-label": "Dismiss trace shortcuts helper", children: jsxRuntimeExports.jsx(X, { className: "h-3 w-3" }) })] });
|
|
2751
|
-
}
|
|
2752
2830
|
const GUTTER_PX = 1;
|
|
2753
2831
|
const MIN_PX = 50;
|
|
2754
2832
|
const DEFAULT_START_PX = 340;
|
|
@@ -2846,6 +2924,57 @@ function SplitPane({ children, className, defaultStartWidth = DEFAULT_START_PX,
|
|
|
2846
2924
|
}
|
|
2847
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] });
|
|
2848
2926
|
}
|
|
2927
|
+
const hint = "_hint_1dmsq_3";
|
|
2928
|
+
const styles = {
|
|
2929
|
+
hint
|
|
2930
|
+
};
|
|
2931
|
+
const DISMISSALS_KEY = "workflow-step-shortcut-helper-dismissals";
|
|
2932
|
+
const DISMISSAL_LIMIT = 3;
|
|
2933
|
+
const HINT_ROTATION_MS = 8e3;
|
|
2934
|
+
function getAltKeyLabel() {
|
|
2935
|
+
if (typeof navigator === "undefined")
|
|
2936
|
+
return "Alt";
|
|
2937
|
+
return navigator.platform.toLowerCase().includes("mac") ? "Option" : "Alt";
|
|
2938
|
+
}
|
|
2939
|
+
function readDismissals() {
|
|
2940
|
+
try {
|
|
2941
|
+
const dismissals = Number.parseInt(window.localStorage.getItem(DISMISSALS_KEY) ?? "0", 10);
|
|
2942
|
+
return Number.isNaN(dismissals) ? 0 : dismissals;
|
|
2943
|
+
} catch {
|
|
2944
|
+
return 0;
|
|
2945
|
+
}
|
|
2946
|
+
}
|
|
2947
|
+
function AltHint() {
|
|
2948
|
+
return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: ["Hold", jsxRuntimeExports.jsx(Kbd, { variant: "outline", size: "compact", className: "mx-1", children: getAltKeyLabel() }), "to see delta between spans"] });
|
|
2949
|
+
}
|
|
2950
|
+
function NavHint() {
|
|
2951
|
+
return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: ["Use", jsxRuntimeExports.jsx(Kbd, { variant: "outline", size: "compact", className: "ml-1", children: "J" }), jsxRuntimeExports.jsx("span", { className: "mx-1", children: "/" }), jsxRuntimeExports.jsx(Kbd, { variant: "outline", size: "compact", className: "mr-1", children: "K" }), "to move between spans"] });
|
|
2952
|
+
}
|
|
2953
|
+
function TraceShortcutHelper({ hasMultipleSpans, reducedMotion }) {
|
|
2954
|
+
const [visible, setVisible] = reactExports.useState(false);
|
|
2955
|
+
const [index, setIndex] = reactExports.useState(0);
|
|
2956
|
+
reactExports.useEffect(() => {
|
|
2957
|
+
setVisible(readDismissals() < DISMISSAL_LIMIT);
|
|
2958
|
+
}, []);
|
|
2959
|
+
reactExports.useEffect(() => {
|
|
2960
|
+
if (reducedMotion)
|
|
2961
|
+
return;
|
|
2962
|
+
const id = setInterval(() => {
|
|
2963
|
+
setIndex((i) => i === 0 ? 1 : 0);
|
|
2964
|
+
}, HINT_ROTATION_MS);
|
|
2965
|
+
return () => clearInterval(id);
|
|
2966
|
+
}, [reducedMotion]);
|
|
2967
|
+
if (!visible || !hasMultipleSpans)
|
|
2968
|
+
return null;
|
|
2969
|
+
const dismiss = () => {
|
|
2970
|
+
try {
|
|
2971
|
+
window.localStorage.setItem(DISMISSALS_KEY, String(readDismissals() + 1));
|
|
2972
|
+
} catch {
|
|
2973
|
+
}
|
|
2974
|
+
setVisible(false);
|
|
2975
|
+
};
|
|
2976
|
+
return jsxRuntimeExports.jsxs("div", { className: "group absolute bottom-3 left-1/2 z-10 hidden h-8 max-w-[calc(100%-2rem)] -translate-x-1/2 items-center gap-1 text-xs leading-none text-gray-900 md:inline-flex", children: [jsxRuntimeExports.jsx("span", { "aria-live": "polite", "aria-atomic": "true", className: "inline-flex items-center whitespace-nowrap", children: reducedMotion ? jsxRuntimeExports.jsx(AltHint, {}) : jsxRuntimeExports.jsx("span", { className: `inline-flex items-center ${styles.hint}`, children: index === 0 ? jsxRuntimeExports.jsx(AltHint, {}) : jsxRuntimeExports.jsx(NavHint, {}) }, index) }), jsxRuntimeExports.jsx("button", { type: "button", className: "inline-flex h-5 w-5 items-center justify-center rounded text-muted-foreground opacity-0 transition-opacity hover:bg-accent hover:text-foreground group-hover:opacity-100 focus-visible:opacity-100 motion-reduce:transition-none", onClick: dismiss, "aria-label": "Dismiss trace shortcuts helper", children: jsxRuntimeExports.jsx(X, { className: "h-3 w-3" }) })] });
|
|
2977
|
+
}
|
|
2849
2978
|
const MIN_VIEWPORT_MS = 1e-3;
|
|
2850
2979
|
const ZOOM_DEBOUNCE_MS = 150;
|
|
2851
2980
|
function useAnimatedViewport(initial) {
|
|
@@ -3256,7 +3385,7 @@ function NewTraceViewerContent({ trace, onLoadMore, hasMore, isLoadingMore }) {
|
|
|
3256
3385
|
e.stopPropagation();
|
|
3257
3386
|
setSearchQuery("");
|
|
3258
3387
|
}
|
|
3259
|
-
}, 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, "aria-label": "Zoom in", children: jsxRuntimeExports.jsx(ZoomIn, { className: "w-4 h-4" }) })] })] }), activeSpan ? jsxRuntimeExports.jsxs("aside", { className: "flex flex-col h-full max-h-full bg-background-100 border-l border-gray-alpha-400 overflow-auto", children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 shrink-0 px-4 pt-3 pb-3", 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: handleSelectPrevSpan, 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: handleSelectNextSpan, 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: handleClearActiveSpan, 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,
|
|
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, "aria-label": "Zoom in", children: jsxRuntimeExports.jsx(ZoomIn, { className: "w-4 h-4" }) })] })] }), activeSpan ? jsxRuntimeExports.jsxs("aside", { className: "flex flex-col h-full max-h-full bg-background-100 border-l border-gray-alpha-400 overflow-auto", children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 shrink-0 px-4 pt-3 pb-3", 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: handleSelectPrevSpan, 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: handleSelectNextSpan, 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: handleClearActiveSpan, 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 }) }) })] }) : null, jsxRuntimeExports.jsx(TraceShortcutHelper, { hasMultipleSpans: trace.spans.length > 1, reducedMotion })] });
|
|
3260
3389
|
}
|
|
3261
3390
|
const NewTraceViewer = ({ run, events, sidebarData, onLoadMore, hasMore, isLoadingMore, loading = false }) => {
|
|
3262
3391
|
const trace = reactExports.useMemo(() => {
|
|
@@ -3298,130 +3427,48 @@ async function fetchResourceWithCorrelationId(env, resource, resourceId, options
|
|
|
3298
3427
|
}
|
|
3299
3428
|
return { data: resourceData, correlationId };
|
|
3300
3429
|
}
|
|
3301
|
-
function
|
|
3302
|
-
const {
|
|
3303
|
-
const
|
|
3304
|
-
|
|
3305
|
-
)
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
setLoading(false);
|
|
3316
|
-
return;
|
|
3317
|
-
}
|
|
3318
|
-
const selectionKey = `${resource}:${resourceId}`;
|
|
3319
|
-
if (selectionKey !== prevSelectionRef.current) {
|
|
3320
|
-
setData(null);
|
|
3321
|
-
prevSelectionRef.current = selectionKey;
|
|
3322
|
-
}
|
|
3323
|
-
setError(null);
|
|
3324
|
-
setLoading(true);
|
|
3325
|
-
if (resource === "hook") {
|
|
3326
|
-
try {
|
|
3327
|
-
const { error: error2, result } = await unwrapServerActionResult(
|
|
3328
|
-
fetchHook(env, resourceId, "all")
|
|
3329
|
-
);
|
|
3330
|
-
if (error2) {
|
|
3331
|
-
setError(error2);
|
|
3332
|
-
return;
|
|
3333
|
-
}
|
|
3334
|
-
try {
|
|
3335
|
-
setData(await hydrate(result));
|
|
3336
|
-
} catch (hydrateError) {
|
|
3337
|
-
setError(
|
|
3338
|
-
hydrateError instanceof Error ? hydrateError : new Error(String(hydrateError))
|
|
3339
|
-
);
|
|
3340
|
-
}
|
|
3341
|
-
} finally {
|
|
3342
|
-
setLoading(false);
|
|
3343
|
-
}
|
|
3344
|
-
return;
|
|
3345
|
-
}
|
|
3346
|
-
if (resource === "sleep") {
|
|
3347
|
-
try {
|
|
3348
|
-
if (!runId) {
|
|
3349
|
-
setError(new Error("runId is required for loading sleep details"));
|
|
3350
|
-
return;
|
|
3351
|
-
}
|
|
3352
|
-
const { error: error2, result } = await unwrapServerActionResult(
|
|
3353
|
-
fetchEvents(env, runId, {
|
|
3354
|
-
sortOrder: "asc",
|
|
3355
|
-
limit: 1e3,
|
|
3356
|
-
withData: true
|
|
3357
|
-
})
|
|
3358
|
-
);
|
|
3359
|
-
if (error2) {
|
|
3360
|
-
setError(error2);
|
|
3361
|
-
return;
|
|
3362
|
-
}
|
|
3363
|
-
try {
|
|
3364
|
-
const allEvents = result.data.map(
|
|
3365
|
-
hydrateResourceIO
|
|
3366
|
-
);
|
|
3367
|
-
const waitEvents = await Promise.all(
|
|
3368
|
-
allEvents.filter((e) => e.correlationId === resourceId).map(hydrate)
|
|
3369
|
-
);
|
|
3370
|
-
const data2 = waitEventsToWaitEntity(waitEvents);
|
|
3371
|
-
if (data2 === null) {
|
|
3372
|
-
setError(
|
|
3373
|
-
new Error(
|
|
3374
|
-
`Failed to load ${resource} details: missing required event data`
|
|
3375
|
-
)
|
|
3376
|
-
);
|
|
3377
|
-
return;
|
|
3378
|
-
}
|
|
3379
|
-
setData(data2);
|
|
3380
|
-
} catch (hydrateError) {
|
|
3381
|
-
setError(
|
|
3382
|
-
hydrateError instanceof Error ? hydrateError : new Error(String(hydrateError))
|
|
3383
|
-
);
|
|
3384
|
-
}
|
|
3385
|
-
} finally {
|
|
3386
|
-
setLoading(false);
|
|
3387
|
-
}
|
|
3388
|
-
return;
|
|
3430
|
+
async function fetchSpanDetailResource(env, selection, options = {}) {
|
|
3431
|
+
const { resource, resourceId, runId } = selection;
|
|
3432
|
+
const { encryptionKey } = options;
|
|
3433
|
+
const hydrate = async (value) => encryptionKey ? hydrateResourceIOWithKey(value, encryptionKey) : hydrateResourceIO(value);
|
|
3434
|
+
if (resource === "hook") {
|
|
3435
|
+
const result = await unwrapOrThrow(fetchHook(env, resourceId, "all"));
|
|
3436
|
+
return hydrate(result);
|
|
3437
|
+
}
|
|
3438
|
+
if (resource === "sleep") {
|
|
3439
|
+
if (!runId) {
|
|
3440
|
+
throw new WorkflowWebAPIError(
|
|
3441
|
+
"runId is required for loading sleep details",
|
|
3442
|
+
{ layer: "client" }
|
|
3443
|
+
);
|
|
3389
3444
|
}
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3445
|
+
const result = await unwrapOrThrow(
|
|
3446
|
+
fetchEvents(env, runId, { sortOrder: "asc", limit: 1e3, withData: true })
|
|
3447
|
+
);
|
|
3448
|
+
const allEvents = result.data.map(
|
|
3449
|
+
hydrateResourceIO
|
|
3450
|
+
);
|
|
3451
|
+
const waitEvents = await Promise.all(
|
|
3452
|
+
allEvents.filter((e) => e.correlationId === resourceId).map(hydrate)
|
|
3453
|
+
);
|
|
3454
|
+
const data2 = waitEventsToWaitEntity(waitEvents);
|
|
3455
|
+
if (data2 === null) {
|
|
3456
|
+
throw new WorkflowWebAPIError(
|
|
3457
|
+
`Failed to load ${resource} details: missing required event data`,
|
|
3458
|
+
{ layer: "client" }
|
|
3396
3459
|
);
|
|
3397
|
-
setData(await hydrate(resourceData));
|
|
3398
|
-
} catch (error2) {
|
|
3399
|
-
if (error2 instanceof Error) {
|
|
3400
|
-
setError(error2);
|
|
3401
|
-
} else {
|
|
3402
|
-
setError(new Error(String(error2)));
|
|
3403
|
-
}
|
|
3404
|
-
return;
|
|
3405
|
-
} finally {
|
|
3406
|
-
setLoading(false);
|
|
3407
3460
|
}
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3461
|
+
return data2;
|
|
3462
|
+
}
|
|
3463
|
+
const { data } = await fetchResourceWithCorrelationId(
|
|
3464
|
+
env,
|
|
3465
|
+
resource,
|
|
3466
|
+
resourceId,
|
|
3467
|
+
{
|
|
3468
|
+
runId
|
|
3415
3469
|
}
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
}, [refreshInterval, fetchData]);
|
|
3419
|
-
return {
|
|
3420
|
-
data,
|
|
3421
|
-
loading,
|
|
3422
|
-
error,
|
|
3423
|
-
refresh: fetchData
|
|
3424
|
-
};
|
|
3470
|
+
);
|
|
3471
|
+
return hydrate(data);
|
|
3425
3472
|
}
|
|
3426
3473
|
function mergeById(prev, next, idKey) {
|
|
3427
3474
|
const combined = [...prev, ...next];
|
|
@@ -5426,30 +5473,15 @@ function RunDetailView({
|
|
|
5426
5473
|
encryptionKey: encryptionKey ?? void 0,
|
|
5427
5474
|
enabled: activeTab === "events"
|
|
5428
5475
|
});
|
|
5429
|
-
const
|
|
5430
|
-
|
|
5431
|
-
);
|
|
5432
|
-
const {
|
|
5433
|
-
data: spanDetailData,
|
|
5434
|
-
loading: spanDetailLoading,
|
|
5435
|
-
error: spanDetailError,
|
|
5436
|
-
refresh: refreshSpanDetail
|
|
5437
|
-
} = useWorkflowResourceData(
|
|
5438
|
-
env,
|
|
5439
|
-
(spanSelection == null ? void 0 : spanSelection.resource) ?? "run",
|
|
5440
|
-
(spanSelection == null ? void 0 : spanSelection.resourceId) ?? "",
|
|
5441
|
-
{
|
|
5442
|
-
runId: spanSelection == null ? void 0 : spanSelection.runId,
|
|
5443
|
-
enabled: Boolean(
|
|
5444
|
-
(spanSelection == null ? void 0 : spanSelection.resource) && (spanSelection == null ? void 0 : spanSelection.resourceId) && spanSelection.resource !== "hook"
|
|
5445
|
-
),
|
|
5476
|
+
const fetchSpanDetail = reactExports.useCallback(
|
|
5477
|
+
(selection) => fetchSpanDetailResource(env, selection, {
|
|
5446
5478
|
encryptionKey: encryptionKey ?? void 0
|
|
5447
|
-
}
|
|
5479
|
+
}),
|
|
5480
|
+
[env, encryptionKey]
|
|
5448
5481
|
);
|
|
5449
5482
|
const [isDecrypting, setIsDecrypting] = reactExports.useState(false);
|
|
5450
5483
|
const handleDecrypt = reactExports.useCallback(async () => {
|
|
5451
5484
|
if (encryptionKey) {
|
|
5452
|
-
refreshSpanDetail();
|
|
5453
5485
|
return;
|
|
5454
5486
|
}
|
|
5455
5487
|
setIsDecrypting(true);
|
|
@@ -5467,18 +5499,12 @@ function RunDetailView({
|
|
|
5467
5499
|
} finally {
|
|
5468
5500
|
setIsDecrypting(false);
|
|
5469
5501
|
}
|
|
5470
|
-
}, [encryptionKey, env, runId
|
|
5471
|
-
const handleSpanSelect = reactExports.useCallback((info) => {
|
|
5472
|
-
setSpanSelection(info);
|
|
5473
|
-
}, []);
|
|
5502
|
+
}, [encryptionKey, env, runId]);
|
|
5474
5503
|
const sidebarData = reactExports.useMemo(
|
|
5475
5504
|
() => ({
|
|
5476
5505
|
run,
|
|
5477
5506
|
events: allEvents ?? [],
|
|
5478
|
-
|
|
5479
|
-
spanDetailError,
|
|
5480
|
-
spanDetailLoading,
|
|
5481
|
-
onSpanSelect: handleSpanSelect,
|
|
5507
|
+
fetchSpanDetail,
|
|
5482
5508
|
onStreamClick: handleStreamClick,
|
|
5483
5509
|
onRunClick: handleRunRefClick,
|
|
5484
5510
|
onWakeUpSleep: handleWakeUpSleep,
|
|
@@ -5492,10 +5518,7 @@ function RunDetailView({
|
|
|
5492
5518
|
[
|
|
5493
5519
|
run,
|
|
5494
5520
|
allEvents,
|
|
5495
|
-
|
|
5496
|
-
spanDetailError,
|
|
5497
|
-
spanDetailLoading,
|
|
5498
|
-
handleSpanSelect,
|
|
5521
|
+
fetchSpanDetail,
|
|
5499
5522
|
handleStreamClick,
|
|
5500
5523
|
handleRunRefClick,
|
|
5501
5524
|
handleWakeUpSleep,
|