@workflow/web 5.0.0-beta.24 → 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-e1cf8511.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-BzGs1YV_.js → run-detail-sr7StYc6.js} +359 -355
- 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-1p4IhK-Q.js → app-e2FYIgWU.js} +5 -1
- package/build/server/assets/{highlighted-body-B3W2YXNL-BlH6gm7c.js → highlighted-body-B3W2YXNL-B7xcG7gl.js} +6 -2
- package/build/server/assets/{index-BOfd00Ok.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-4IS2FONM.js → mermaid-3ZIDBTTL-DQqBhQ9Y.js} +6 -2
- package/build/server/assets/{server-build-CpnmV4F1.js → server-build-D7EgG_DH.js} +740 -532
- package/build/server/assets/{token-fPsafoXW.js → token-guLCf66r.js} +6 -2
- package/build/server/assets/{token-util-MV-dKCwg.js → token-util-CCeU4-vR.js} +6 -2
- package/build/server/assets/{zstd-browser-decoder-embi2ab_.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,24 +1111,17 @@ const MARKER_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
|
1081
1111
|
"wait_completed",
|
|
1082
1112
|
"attr_set"
|
|
1083
1113
|
]);
|
|
1084
|
-
const
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
return void 0;
|
|
1091
|
-
};
|
|
1092
|
-
const withOccurredAt = (entity, occurredAt) => {
|
|
1093
|
-
if (!occurredAt || entity.occurredAt != null) {
|
|
1094
|
-
return entity;
|
|
1095
|
-
}
|
|
1096
|
-
return { ...entity, occurredAt };
|
|
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;
|
|
1097
1120
|
};
|
|
1098
|
-
function convertEventsToSpanEvents(events, filterTypes = true) {
|
|
1121
|
+
function convertEventsToSpanEvents(events, filterTypes = true, options = {}) {
|
|
1099
1122
|
return events.filter((event) => filterTypes ? MARKER_EVENT_TYPES.has(event.eventType) : true).map((event) => ({
|
|
1100
1123
|
name: event.eventType,
|
|
1101
|
-
timestamp: dateToOtelTime(event.createdAt),
|
|
1124
|
+
timestamp: dateToOtelTime(options.preferOccurredAt ? getEventTimestamp(event) ?? event.createdAt : event.createdAt),
|
|
1102
1125
|
attributes: {
|
|
1103
1126
|
eventId: event.eventId,
|
|
1104
1127
|
correlationId: event.correlationId,
|
|
@@ -1115,13 +1138,13 @@ const waitEventsToWaitEntity = (events) => {
|
|
|
1115
1138
|
return null;
|
|
1116
1139
|
}
|
|
1117
1140
|
const completedEvent = events.find((event) => event.eventType === "wait_completed");
|
|
1118
|
-
return
|
|
1141
|
+
return {
|
|
1119
1142
|
waitId: startEvent.correlationId,
|
|
1120
1143
|
runId: startEvent.runId,
|
|
1121
|
-
createdAt: startEvent.createdAt,
|
|
1144
|
+
createdAt: getEventTimestamp(startEvent) ?? startEvent.createdAt,
|
|
1122
1145
|
resumeAt: ((_a = startEvent.eventData) == null ? void 0 : _a.resumeAt) ? new Date(startEvent.eventData.resumeAt) : void 0,
|
|
1123
|
-
completedAt: completedEvent
|
|
1124
|
-
}
|
|
1146
|
+
completedAt: getEventTimestamp(completedEvent)
|
|
1147
|
+
};
|
|
1125
1148
|
};
|
|
1126
1149
|
function waitToSpan(events, maxEndTime, fallbackEndTime = maxEndTime) {
|
|
1127
1150
|
const wait = waitEventsToWaitEntity(events);
|
|
@@ -1177,16 +1200,16 @@ const stepEventsToStepEntity = (events) => {
|
|
|
1177
1200
|
status = "running";
|
|
1178
1201
|
attempt += 1;
|
|
1179
1202
|
if (!startedAt)
|
|
1180
|
-
startedAt = e.createdAt;
|
|
1203
|
+
startedAt = getEventTimestamp(e) ?? e.createdAt;
|
|
1181
1204
|
completedAt = void 0;
|
|
1182
1205
|
break;
|
|
1183
1206
|
case "step_completed":
|
|
1184
1207
|
status = "completed";
|
|
1185
|
-
completedAt = e.createdAt;
|
|
1208
|
+
completedAt = getEventTimestamp(e) ?? e.createdAt;
|
|
1186
1209
|
break;
|
|
1187
1210
|
case "step_failed":
|
|
1188
1211
|
status = "failed";
|
|
1189
|
-
completedAt = e.createdAt;
|
|
1212
|
+
completedAt = getEventTimestamp(e) ?? e.createdAt;
|
|
1190
1213
|
break;
|
|
1191
1214
|
case "step_retrying":
|
|
1192
1215
|
status = "pending";
|
|
@@ -1197,19 +1220,18 @@ const stepEventsToStepEntity = (events) => {
|
|
|
1197
1220
|
if (attempt === 0)
|
|
1198
1221
|
attempt = 1;
|
|
1199
1222
|
const lastEvent = events[events.length - 1];
|
|
1200
|
-
|
|
1201
|
-
return withOccurredAt({
|
|
1223
|
+
return {
|
|
1202
1224
|
stepId: anchorEvent.correlationId ?? "",
|
|
1203
1225
|
runId: anchorEvent.runId,
|
|
1204
1226
|
stepName: ((_a = createdEvent == null ? void 0 : createdEvent.eventData) == null ? void 0 : _a.stepName) ?? "",
|
|
1205
1227
|
status,
|
|
1206
1228
|
attempt,
|
|
1207
|
-
createdAt: anchorEvent.createdAt,
|
|
1208
|
-
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,
|
|
1209
1231
|
startedAt,
|
|
1210
1232
|
completedAt,
|
|
1211
1233
|
specVersion: anchorEvent.specVersion
|
|
1212
|
-
}
|
|
1234
|
+
};
|
|
1213
1235
|
};
|
|
1214
1236
|
function stepToSpan(stepEvents, maxEndTime) {
|
|
1215
1237
|
const step = stepEventsToStepEntity(stepEvents);
|
|
@@ -1222,13 +1244,20 @@ function stepToSpan(stepEvents, maxEndTime) {
|
|
|
1222
1244
|
data: step
|
|
1223
1245
|
};
|
|
1224
1246
|
const resource = "step";
|
|
1225
|
-
const
|
|
1226
|
-
|
|
1227
|
-
|
|
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);
|
|
1228
1252
|
let activeStartTime = step.startedAt ? new Date(step.startedAt) : void 0;
|
|
1229
1253
|
const firstStartEvent = stepEvents.find((event) => event.eventType === "step_started");
|
|
1230
1254
|
if (firstStartEvent) {
|
|
1231
|
-
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);
|
|
1232
1261
|
}
|
|
1233
1262
|
return {
|
|
1234
1263
|
spanId: String(step.stepId),
|
|
@@ -1250,7 +1279,7 @@ function stepToSpan(stepEvents, maxEndTime) {
|
|
|
1250
1279
|
};
|
|
1251
1280
|
}
|
|
1252
1281
|
const hookEventsToHookEntity = (events) => {
|
|
1253
|
-
var _a
|
|
1282
|
+
var _a;
|
|
1254
1283
|
const createdEvent = events.find((event) => event.eventType === "hook_created");
|
|
1255
1284
|
if (!createdEvent) {
|
|
1256
1285
|
return null;
|
|
@@ -1258,15 +1287,15 @@ const hookEventsToHookEntity = (events) => {
|
|
|
1258
1287
|
const receivedEvents = events.filter((event) => event.eventType === "hook_received");
|
|
1259
1288
|
const disposedEvents = events.filter((event) => event.eventType === "hook_disposed");
|
|
1260
1289
|
const lastReceivedEvent = receivedEvents.at(-1);
|
|
1261
|
-
return
|
|
1290
|
+
return {
|
|
1262
1291
|
hookId: createdEvent.correlationId,
|
|
1263
1292
|
runId: createdEvent.runId,
|
|
1264
1293
|
token: (_a = createdEvent.eventData) == null ? void 0 : _a.token,
|
|
1265
|
-
createdAt: createdEvent.createdAt,
|
|
1294
|
+
createdAt: getEventTimestamp(createdEvent) ?? createdEvent.createdAt,
|
|
1266
1295
|
receivedCount: receivedEvents.length,
|
|
1267
|
-
lastReceivedAt: (lastReceivedEvent
|
|
1268
|
-
disposedAt: (
|
|
1269
|
-
}
|
|
1296
|
+
lastReceivedAt: getEventTimestamp(lastReceivedEvent),
|
|
1297
|
+
disposedAt: getEventTimestamp(disposedEvents.at(-1))
|
|
1298
|
+
};
|
|
1270
1299
|
};
|
|
1271
1300
|
function hookToSpan(hookEvents, maxEndTime) {
|
|
1272
1301
|
const hook = hookEventsToHookEntity(hookEvents);
|
|
@@ -1298,19 +1327,26 @@ function hookToSpan(hookEvents, maxEndTime) {
|
|
|
1298
1327
|
function runToSpan(run, runEvents, nowTime) {
|
|
1299
1328
|
var _a;
|
|
1300
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;
|
|
1301
1337
|
const { input: _i, output: _o, error: _e, ...runIdentity } = run;
|
|
1302
|
-
const occurrenceEvent = findEventByType(runEvents, [
|
|
1303
|
-
"run_created",
|
|
1304
|
-
"run_started"
|
|
1305
|
-
]);
|
|
1306
1338
|
const attributes = {
|
|
1307
1339
|
resource: "run",
|
|
1308
|
-
data:
|
|
1340
|
+
data: {
|
|
1341
|
+
...runIdentity,
|
|
1342
|
+
createdAt: spanStartTime,
|
|
1343
|
+
startedAt: activeStartTime,
|
|
1344
|
+
completedAt
|
|
1345
|
+
}
|
|
1309
1346
|
};
|
|
1310
|
-
const
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
const events = convertEventsToSpanEvents(runEvents, false);
|
|
1347
|
+
const events = convertEventsToSpanEvents(runEvents, false, {
|
|
1348
|
+
preferOccurredAt: true
|
|
1349
|
+
});
|
|
1314
1350
|
return {
|
|
1315
1351
|
spanId: String(run.runId),
|
|
1316
1352
|
name: String(((_a = parseWorkflowName(run.workflowName)) == null ? void 0 : _a.shortName) ?? "?"),
|
|
@@ -1380,7 +1416,7 @@ function groupEventsByCorrelation(events) {
|
|
|
1380
1416
|
function computeLatestKnownTime(events, run) {
|
|
1381
1417
|
let latest = new Date(run.createdAt).getTime();
|
|
1382
1418
|
for (const event of events) {
|
|
1383
|
-
const t = new Date(event.createdAt).getTime();
|
|
1419
|
+
const t = (getEventTimestamp(event) ?? new Date(event.createdAt)).getTime();
|
|
1384
1420
|
if (t > latest)
|
|
1385
1421
|
latest = t;
|
|
1386
1422
|
}
|
|
@@ -1973,7 +2009,7 @@ const getModuleSpecifierFromName = (value) => {
|
|
|
1973
2009
|
}
|
|
1974
2010
|
return raw;
|
|
1975
2011
|
};
|
|
1976
|
-
const parseDateValue = (value) => {
|
|
2012
|
+
const parseDateValue$1 = (value) => {
|
|
1977
2013
|
if (value == null) {
|
|
1978
2014
|
return null;
|
|
1979
2015
|
}
|
|
@@ -1988,14 +2024,14 @@ const parseDateValue = (value) => {
|
|
|
1988
2024
|
};
|
|
1989
2025
|
const formatLocalMillisecondTime = (date) => format(date, "MMM dd HH:mm:ss.SS OO").toUpperCase();
|
|
1990
2026
|
const localMillisecondTimeOrNull = (value) => {
|
|
1991
|
-
const date = parseDateValue(value);
|
|
2027
|
+
const date = parseDateValue$1(value);
|
|
1992
2028
|
if (!date) {
|
|
1993
2029
|
return null;
|
|
1994
2030
|
}
|
|
1995
2031
|
return formatLocalMillisecondTime(date);
|
|
1996
2032
|
};
|
|
1997
2033
|
const timestampWithTooltipOrNull = (value) => {
|
|
1998
|
-
const date = parseDateValue(value);
|
|
2034
|
+
const date = parseDateValue$1(value);
|
|
1999
2035
|
if (!date)
|
|
2000
2036
|
return null;
|
|
2001
2037
|
return jsxRuntimeExports.jsx(TimestampTooltip, { date, children: jsxRuntimeExports.jsx("span", { children: formatLocalMillisecondTime(date) }) });
|
|
@@ -2202,8 +2238,8 @@ const AttributePanel = ({ data, moduleSpecifier, isLoading, error, expiredAt, on
|
|
|
2202
2238
|
return present;
|
|
2203
2239
|
if (resource === "sleep")
|
|
2204
2240
|
return present;
|
|
2205
|
-
const
|
|
2206
|
-
for (const key of
|
|
2241
|
+
const loadingPlaceholders = ["input", "output"];
|
|
2242
|
+
for (const key of loadingPlaceholders) {
|
|
2207
2243
|
if (!present.includes(key)) {
|
|
2208
2244
|
present.push(key);
|
|
2209
2245
|
}
|
|
@@ -2268,7 +2304,23 @@ const DATA_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
|
2268
2304
|
"wait_completed",
|
|
2269
2305
|
"attr_set"
|
|
2270
2306
|
]);
|
|
2271
|
-
|
|
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 }) {
|
|
2272
2324
|
const [loadedData, setLoadedData] = reactExports.useState(null);
|
|
2273
2325
|
const [isLoading, setIsLoading] = reactExports.useState(false);
|
|
2274
2326
|
const [loadError, setLoadError] = reactExports.useState(null);
|
|
@@ -2309,16 +2361,18 @@ function EventItem({ event, onLoadEventData, encryptionKey }) {
|
|
|
2309
2361
|
void loadEventData({ force: true });
|
|
2310
2362
|
}, [encryptionKey, loadEventData]);
|
|
2311
2363
|
const createdAt = new Date(event.createdAt);
|
|
2312
|
-
const
|
|
2364
|
+
const occurredAt = parseDateValue(event.occurredAt);
|
|
2365
|
+
const displayedCreatedAt = showSeparateEventOccurrenceTimestamps ? createdAt : getEffectiveEventDate(event);
|
|
2366
|
+
const displayedCreatedAtTime = displayedCreatedAt.toLocaleTimeString(void 0, {
|
|
2313
2367
|
hour: "numeric",
|
|
2314
2368
|
minute: "numeric",
|
|
2315
2369
|
second: "numeric"
|
|
2316
2370
|
});
|
|
2317
2371
|
const displayPayload = isLoading ? loadedData : mergedDisplay;
|
|
2318
|
-
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) => {
|
|
2319
2373
|
if (open)
|
|
2320
2374
|
handleExpand();
|
|
2321
|
-
} : 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 }) })] });
|
|
2322
2376
|
}
|
|
2323
2377
|
function hasOnlyExpiredFields(data, eventType) {
|
|
2324
2378
|
if (data === null || typeof data !== "object" || Array.isArray(data)) {
|
|
@@ -2354,15 +2408,52 @@ function EventDataBlock({ eventType, data }) {
|
|
|
2354
2408
|
}
|
|
2355
2409
|
return jsxRuntimeExports.jsx(CopyableDataBlock, { data });
|
|
2356
2410
|
}
|
|
2357
|
-
function EventsList({ events, isLoading = false, error, onLoadEventData, onStreamClick, onRunClick, encryptionKey }) {
|
|
2358
|
-
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]);
|
|
2359
2413
|
const hasEvents = sortedEvents.length > 0 && !error;
|
|
2360
2414
|
if (!hasEvents && !isLoading) {
|
|
2361
2415
|
return jsxRuntimeExports.jsx(DetailCard, { summary: "Events", disabled: true });
|
|
2362
2416
|
}
|
|
2363
|
-
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)) }) }) }) });
|
|
2364
2418
|
}
|
|
2365
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
|
+
}
|
|
2366
2457
|
function spanDetailMatchesSelection(detail, resource, resourceId) {
|
|
2367
2458
|
if (!detail || typeof detail !== "object" || !resource || !resourceId) {
|
|
2368
2459
|
return false;
|
|
@@ -2395,16 +2486,88 @@ function mergeSpanDetail(spanData, detail) {
|
|
|
2395
2486
|
}
|
|
2396
2487
|
return merged;
|
|
2397
2488
|
}
|
|
2398
|
-
function
|
|
2399
|
-
|
|
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;
|
|
2400
2514
|
}
|
|
2401
|
-
function
|
|
2402
|
-
|
|
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
|
+
};
|
|
2403
2566
|
}
|
|
2404
2567
|
function isHook(data) {
|
|
2405
2568
|
return data !== null && typeof data === "object" && "hookId" in data;
|
|
2406
2569
|
}
|
|
2407
|
-
function EntityDetailPanel({ run, onStreamClick, onRunClick,
|
|
2570
|
+
function EntityDetailPanel({ run, onStreamClick, onRunClick, fetchSpanDetail, onWakeUpSleep, onLoadEventData, onResolveHook, encryptionKey, onDecrypt, isDecrypting = false, selectedSpan, showSeparateEventOccurrenceTimestamps = false }) {
|
|
2408
2571
|
const toast2 = useToast();
|
|
2409
2572
|
const [stoppingSleep, setStoppingSleep] = reactExports.useState(false);
|
|
2410
2573
|
const [showResolveHookModal, setShowResolveHookModal] = reactExports.useState(false);
|
|
@@ -2415,41 +2578,8 @@ function EntityDetailPanel({ run, onStreamClick, onRunClick, spanDetailData, spa
|
|
|
2415
2578
|
const data = selectedSpan == null ? void 0 : selectedSpan.data;
|
|
2416
2579
|
const rawEvents = selectedSpan == null ? void 0 : selectedSpan.rawEvents;
|
|
2417
2580
|
const rawEventsLength = (rawEvents == null ? void 0 : rawEvents.length) ?? 0;
|
|
2418
|
-
const { resource, resourceId,
|
|
2419
|
-
|
|
2420
|
-
return { resource: void 0, resourceId: void 0, runId: void 0 };
|
|
2421
|
-
}
|
|
2422
|
-
const res = selectedSpan.resource;
|
|
2423
|
-
if (res === "step" && isStep(data)) {
|
|
2424
|
-
return { resource: "step", resourceId: data.stepId, runId: data.runId };
|
|
2425
|
-
}
|
|
2426
|
-
if (res === "run" && isWorkflowRun(data)) {
|
|
2427
|
-
return { resource: "run", resourceId: data.runId, runId: void 0 };
|
|
2428
|
-
}
|
|
2429
|
-
if (res === "hook" && isHook(data)) {
|
|
2430
|
-
return { resource: "hook", resourceId: data.hookId, runId: void 0 };
|
|
2431
|
-
}
|
|
2432
|
-
if (res === "sleep") {
|
|
2433
|
-
const waitData = data;
|
|
2434
|
-
return {
|
|
2435
|
-
resource: "sleep",
|
|
2436
|
-
resourceId: selectedSpan.spanId,
|
|
2437
|
-
runId: waitData == null ? void 0 : waitData.runId
|
|
2438
|
-
};
|
|
2439
|
-
}
|
|
2440
|
-
return { resource: void 0, resourceId: void 0, runId: void 0 };
|
|
2441
|
-
}, [selectedSpan, data]);
|
|
2442
|
-
const onSpanSelectRef = reactExports.useRef(onSpanSelect);
|
|
2443
|
-
onSpanSelectRef.current = onSpanSelect;
|
|
2444
|
-
reactExports.useEffect(() => {
|
|
2445
|
-
if (resource && resourceId && ["run", "step", "hook", "sleep"].includes(resource)) {
|
|
2446
|
-
onSpanSelectRef.current({
|
|
2447
|
-
resource,
|
|
2448
|
-
resourceId,
|
|
2449
|
-
runId
|
|
2450
|
-
});
|
|
2451
|
-
}
|
|
2452
|
-
}, [resource, resourceId, runId]);
|
|
2581
|
+
const { status, resource, resourceId, displayData, detail: matchedSpanDetailData, error } = useSelectedSpanDetail(selectedSpan, fetchSpanDetail);
|
|
2582
|
+
const loading = status === "loading";
|
|
2453
2583
|
const canWakeUp = reactExports.useMemo(() => {
|
|
2454
2584
|
if (resource !== "sleep" || !rawEvents)
|
|
2455
2585
|
return false;
|
|
@@ -2482,9 +2612,6 @@ function EntityDetailPanel({ run, onStreamClick, onRunClick, spanDetailData, spa
|
|
|
2482
2612
|
run.status,
|
|
2483
2613
|
resolvedHookIds
|
|
2484
2614
|
]);
|
|
2485
|
-
const error = spanDetailError ?? void 0;
|
|
2486
|
-
const loading = spanDetailLoading ?? false;
|
|
2487
|
-
const matchedSpanDetailData = reactExports.useMemo(() => spanDetailMatchesSelection(spanDetailData, resource, resourceId) ? spanDetailData : null, [spanDetailData, resource, resourceId]);
|
|
2488
2615
|
const hookToken = reactExports.useMemo(() => {
|
|
2489
2616
|
if (resource !== "hook" || !resourceId)
|
|
2490
2617
|
return void 0;
|
|
@@ -2569,7 +2696,6 @@ function EntityDetailPanel({ run, onStreamClick, onRunClick, spanDetailData, spa
|
|
|
2569
2696
|
setResolvingHook(false);
|
|
2570
2697
|
}
|
|
2571
2698
|
}, [onResolveHook, hookToken, resolvingHook, matchedSpanDetailData, data]);
|
|
2572
|
-
const displayData = reactExports.useMemo(() => mergeSpanDetail(data, matchedSpanDetailData), [data, matchedSpanDetailData]);
|
|
2573
2699
|
const moduleSpecifier = reactExports.useMemo(() => {
|
|
2574
2700
|
const displayRecord = displayData;
|
|
2575
2701
|
const displayStepName = displayRecord.stepName;
|
|
@@ -2598,43 +2724,7 @@ function EntityDetailPanel({ run, onStreamClick, onRunClick, spanDetailData, spa
|
|
|
2598
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: {
|
|
2599
2725
|
background: "var(--ds-gray-1000)",
|
|
2600
2726
|
color: "var(--ds-background-100)"
|
|
2601
|
-
}, 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 })] });
|
|
2602
|
-
}
|
|
2603
|
-
const kbdVariants = cva("inline-flex items-center justify-center rounded px-1 text-center font-sans", {
|
|
2604
|
-
variants: {
|
|
2605
|
-
variant: {
|
|
2606
|
-
subtle: "bg-background-100/20",
|
|
2607
|
-
outline: "border border-gray-alpha-400 bg-background-100 font-medium text-gray-900"
|
|
2608
|
-
},
|
|
2609
|
-
size: {
|
|
2610
|
-
default: "h-5 min-w-5 text-xs leading-none",
|
|
2611
|
-
compact: "h-4 min-h-4 min-w-4 text-[11px] leading-none",
|
|
2612
|
-
search: "h-5 min-h-5 min-w-5 text-[13px] leading-[1.7em]"
|
|
2613
|
-
}
|
|
2614
|
-
},
|
|
2615
|
-
defaultVariants: {
|
|
2616
|
-
variant: "subtle",
|
|
2617
|
-
size: "default"
|
|
2618
|
-
}
|
|
2619
|
-
});
|
|
2620
|
-
function Kbd({ children, className, variant, size, ...props }) {
|
|
2621
|
-
return jsxRuntimeExports.jsx("kbd", { className: cn(kbdVariants({ variant, size, className })), ...props, children });
|
|
2622
|
-
}
|
|
2623
|
-
const COL_TEMPLATE = "340px 1px minmax(50px, 1fr)";
|
|
2624
|
-
const ROWS = [
|
|
2625
|
-
{ id: "r0", name: 62, off: 0, bar: 72 },
|
|
2626
|
-
{ id: "r1", name: 78, off: 6, bar: 48 },
|
|
2627
|
-
{ id: "r2", name: 50, off: 10, bar: 55 },
|
|
2628
|
-
{ id: "r3", name: 84, off: 18, bar: 30 },
|
|
2629
|
-
{ id: "r4", name: 45, off: 18, bar: 42 },
|
|
2630
|
-
{ id: "r5", name: 66, off: 34, bar: 38 },
|
|
2631
|
-
{ id: "r6", name: 55, off: 41, bar: 25 },
|
|
2632
|
-
{ id: "r7", name: 40, off: 50, bar: 30 }
|
|
2633
|
-
];
|
|
2634
|
-
const HEADER_MARKERS = ["m0", "m1", "m2", "m3"];
|
|
2635
|
-
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" }) });
|
|
2636
|
-
function TraceViewerSkeleton() {
|
|
2637
|
-
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 })] });
|
|
2638
2728
|
}
|
|
2639
2729
|
function useIntersectionObserver(elementRef, { threshold = 0, rootRef, rootMargin = "0%", freezeOnceVisible = false } = {}) {
|
|
2640
2730
|
const [entry, setEntry] = reactExports.useState();
|
|
@@ -2671,6 +2761,26 @@ function useLoadMoreOnScroll(loadMore, { hasMore, isLoadingMore, rootRef, rootMa
|
|
|
2671
2761
|
}, [entry == null ? void 0 : entry.isIntersecting, hasMore, isLoadingMore]);
|
|
2672
2762
|
return sentinelRef;
|
|
2673
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
|
+
}
|
|
2674
2784
|
const WorkflowIcon = () => {
|
|
2675
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" }) });
|
|
2676
2786
|
};
|
|
@@ -2717,57 +2827,6 @@ const EventList = ({ spans, activeSpanId, searchResult, onSelectSpan }) => {
|
|
|
2717
2827
|
paddingBottom: (spans.length - end) * ROW_HEIGHT_PX
|
|
2718
2828
|
}, children: spans.slice(start, end).map((span) => jsxRuntimeExports.jsx(EventRow, { span, isSelected: span.spanId === activeSpanId, isDimmed: isSpanDimmedBySearch(span.spanId, searchResult), onSelectSpan }, span.spanId)) });
|
|
2719
2829
|
};
|
|
2720
|
-
const hint = "_hint_1dmsq_3";
|
|
2721
|
-
const styles = {
|
|
2722
|
-
hint
|
|
2723
|
-
};
|
|
2724
|
-
const DISMISSALS_KEY = "workflow-step-shortcut-helper-dismissals";
|
|
2725
|
-
const DISMISSAL_LIMIT = 3;
|
|
2726
|
-
const HINT_ROTATION_MS = 8e3;
|
|
2727
|
-
function getAltKeyLabel() {
|
|
2728
|
-
if (typeof navigator === "undefined")
|
|
2729
|
-
return "Alt";
|
|
2730
|
-
return navigator.platform.toLowerCase().includes("mac") ? "Option" : "Alt";
|
|
2731
|
-
}
|
|
2732
|
-
function readDismissals() {
|
|
2733
|
-
try {
|
|
2734
|
-
const dismissals = Number.parseInt(window.localStorage.getItem(DISMISSALS_KEY) ?? "0", 10);
|
|
2735
|
-
return Number.isNaN(dismissals) ? 0 : dismissals;
|
|
2736
|
-
} catch {
|
|
2737
|
-
return 0;
|
|
2738
|
-
}
|
|
2739
|
-
}
|
|
2740
|
-
function AltHint() {
|
|
2741
|
-
return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: ["Hold", jsxRuntimeExports.jsx(Kbd, { variant: "outline", size: "compact", className: "mx-1", children: getAltKeyLabel() }), "to see delta between spans"] });
|
|
2742
|
-
}
|
|
2743
|
-
function NavHint() {
|
|
2744
|
-
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"] });
|
|
2745
|
-
}
|
|
2746
|
-
function TraceShortcutHelper({ hasMultipleSpans, reducedMotion }) {
|
|
2747
|
-
const [visible, setVisible] = reactExports.useState(false);
|
|
2748
|
-
const [index, setIndex] = reactExports.useState(0);
|
|
2749
|
-
reactExports.useEffect(() => {
|
|
2750
|
-
setVisible(readDismissals() < DISMISSAL_LIMIT);
|
|
2751
|
-
}, []);
|
|
2752
|
-
reactExports.useEffect(() => {
|
|
2753
|
-
if (reducedMotion)
|
|
2754
|
-
return;
|
|
2755
|
-
const id = setInterval(() => {
|
|
2756
|
-
setIndex((i) => i === 0 ? 1 : 0);
|
|
2757
|
-
}, HINT_ROTATION_MS);
|
|
2758
|
-
return () => clearInterval(id);
|
|
2759
|
-
}, [reducedMotion]);
|
|
2760
|
-
if (!visible || !hasMultipleSpans)
|
|
2761
|
-
return null;
|
|
2762
|
-
const dismiss = () => {
|
|
2763
|
-
try {
|
|
2764
|
-
window.localStorage.setItem(DISMISSALS_KEY, String(readDismissals() + 1));
|
|
2765
|
-
} catch {
|
|
2766
|
-
}
|
|
2767
|
-
setVisible(false);
|
|
2768
|
-
};
|
|
2769
|
-
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" }) })] });
|
|
2770
|
-
}
|
|
2771
2830
|
const GUTTER_PX = 1;
|
|
2772
2831
|
const MIN_PX = 50;
|
|
2773
2832
|
const DEFAULT_START_PX = 340;
|
|
@@ -2865,6 +2924,57 @@ function SplitPane({ children, className, defaultStartWidth = DEFAULT_START_PX,
|
|
|
2865
2924
|
}
|
|
2866
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] });
|
|
2867
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
|
+
}
|
|
2868
2978
|
const MIN_VIEWPORT_MS = 1e-3;
|
|
2869
2979
|
const ZOOM_DEBOUNCE_MS = 150;
|
|
2870
2980
|
function useAnimatedViewport(initial) {
|
|
@@ -3275,7 +3385,7 @@ function NewTraceViewerContent({ trace, onLoadMore, hasMore, isLoadingMore }) {
|
|
|
3275
3385
|
e.stopPropagation();
|
|
3276
3386
|
setSearchQuery("");
|
|
3277
3387
|
}
|
|
3278
|
-
}, 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 })] });
|
|
3279
3389
|
}
|
|
3280
3390
|
const NewTraceViewer = ({ run, events, sidebarData, onLoadMore, hasMore, isLoadingMore, loading = false }) => {
|
|
3281
3391
|
const trace = reactExports.useMemo(() => {
|
|
@@ -3317,130 +3427,48 @@ async function fetchResourceWithCorrelationId(env, resource, resourceId, options
|
|
|
3317
3427
|
}
|
|
3318
3428
|
return { data: resourceData, correlationId };
|
|
3319
3429
|
}
|
|
3320
|
-
function
|
|
3321
|
-
const {
|
|
3322
|
-
const
|
|
3323
|
-
|
|
3324
|
-
)
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
setLoading(false);
|
|
3335
|
-
return;
|
|
3336
|
-
}
|
|
3337
|
-
const selectionKey = `${resource}:${resourceId}`;
|
|
3338
|
-
if (selectionKey !== prevSelectionRef.current) {
|
|
3339
|
-
setData(null);
|
|
3340
|
-
prevSelectionRef.current = selectionKey;
|
|
3341
|
-
}
|
|
3342
|
-
setError(null);
|
|
3343
|
-
setLoading(true);
|
|
3344
|
-
if (resource === "hook") {
|
|
3345
|
-
try {
|
|
3346
|
-
const { error: error2, result } = await unwrapServerActionResult(
|
|
3347
|
-
fetchHook(env, resourceId, "all")
|
|
3348
|
-
);
|
|
3349
|
-
if (error2) {
|
|
3350
|
-
setError(error2);
|
|
3351
|
-
return;
|
|
3352
|
-
}
|
|
3353
|
-
try {
|
|
3354
|
-
setData(await hydrate(result));
|
|
3355
|
-
} catch (hydrateError) {
|
|
3356
|
-
setError(
|
|
3357
|
-
hydrateError instanceof Error ? hydrateError : new Error(String(hydrateError))
|
|
3358
|
-
);
|
|
3359
|
-
}
|
|
3360
|
-
} finally {
|
|
3361
|
-
setLoading(false);
|
|
3362
|
-
}
|
|
3363
|
-
return;
|
|
3364
|
-
}
|
|
3365
|
-
if (resource === "sleep") {
|
|
3366
|
-
try {
|
|
3367
|
-
if (!runId) {
|
|
3368
|
-
setError(new Error("runId is required for loading sleep details"));
|
|
3369
|
-
return;
|
|
3370
|
-
}
|
|
3371
|
-
const { error: error2, result } = await unwrapServerActionResult(
|
|
3372
|
-
fetchEvents(env, runId, {
|
|
3373
|
-
sortOrder: "asc",
|
|
3374
|
-
limit: 1e3,
|
|
3375
|
-
withData: true
|
|
3376
|
-
})
|
|
3377
|
-
);
|
|
3378
|
-
if (error2) {
|
|
3379
|
-
setError(error2);
|
|
3380
|
-
return;
|
|
3381
|
-
}
|
|
3382
|
-
try {
|
|
3383
|
-
const allEvents = result.data.map(
|
|
3384
|
-
hydrateResourceIO
|
|
3385
|
-
);
|
|
3386
|
-
const waitEvents = await Promise.all(
|
|
3387
|
-
allEvents.filter((e) => e.correlationId === resourceId).map(hydrate)
|
|
3388
|
-
);
|
|
3389
|
-
const data2 = waitEventsToWaitEntity(waitEvents);
|
|
3390
|
-
if (data2 === null) {
|
|
3391
|
-
setError(
|
|
3392
|
-
new Error(
|
|
3393
|
-
`Failed to load ${resource} details: missing required event data`
|
|
3394
|
-
)
|
|
3395
|
-
);
|
|
3396
|
-
return;
|
|
3397
|
-
}
|
|
3398
|
-
setData(data2);
|
|
3399
|
-
} catch (hydrateError) {
|
|
3400
|
-
setError(
|
|
3401
|
-
hydrateError instanceof Error ? hydrateError : new Error(String(hydrateError))
|
|
3402
|
-
);
|
|
3403
|
-
}
|
|
3404
|
-
} finally {
|
|
3405
|
-
setLoading(false);
|
|
3406
|
-
}
|
|
3407
|
-
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
|
+
);
|
|
3408
3444
|
}
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
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" }
|
|
3415
3459
|
);
|
|
3416
|
-
setData(await hydrate(resourceData));
|
|
3417
|
-
} catch (error2) {
|
|
3418
|
-
if (error2 instanceof Error) {
|
|
3419
|
-
setError(error2);
|
|
3420
|
-
} else {
|
|
3421
|
-
setError(new Error(String(error2)));
|
|
3422
|
-
}
|
|
3423
|
-
return;
|
|
3424
|
-
} finally {
|
|
3425
|
-
setLoading(false);
|
|
3426
3460
|
}
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3461
|
+
return data2;
|
|
3462
|
+
}
|
|
3463
|
+
const { data } = await fetchResourceWithCorrelationId(
|
|
3464
|
+
env,
|
|
3465
|
+
resource,
|
|
3466
|
+
resourceId,
|
|
3467
|
+
{
|
|
3468
|
+
runId
|
|
3434
3469
|
}
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
}, [refreshInterval, fetchData]);
|
|
3438
|
-
return {
|
|
3439
|
-
data,
|
|
3440
|
-
loading,
|
|
3441
|
-
error,
|
|
3442
|
-
refresh: fetchData
|
|
3443
|
-
};
|
|
3470
|
+
);
|
|
3471
|
+
return hydrate(data);
|
|
3444
3472
|
}
|
|
3445
3473
|
function mergeById(prev, next, idKey) {
|
|
3446
3474
|
const combined = [...prev, ...next];
|
|
@@ -5445,30 +5473,15 @@ function RunDetailView({
|
|
|
5445
5473
|
encryptionKey: encryptionKey ?? void 0,
|
|
5446
5474
|
enabled: activeTab === "events"
|
|
5447
5475
|
});
|
|
5448
|
-
const
|
|
5449
|
-
|
|
5450
|
-
);
|
|
5451
|
-
const {
|
|
5452
|
-
data: spanDetailData,
|
|
5453
|
-
loading: spanDetailLoading,
|
|
5454
|
-
error: spanDetailError,
|
|
5455
|
-
refresh: refreshSpanDetail
|
|
5456
|
-
} = useWorkflowResourceData(
|
|
5457
|
-
env,
|
|
5458
|
-
(spanSelection == null ? void 0 : spanSelection.resource) ?? "run",
|
|
5459
|
-
(spanSelection == null ? void 0 : spanSelection.resourceId) ?? "",
|
|
5460
|
-
{
|
|
5461
|
-
runId: spanSelection == null ? void 0 : spanSelection.runId,
|
|
5462
|
-
enabled: Boolean(
|
|
5463
|
-
(spanSelection == null ? void 0 : spanSelection.resource) && (spanSelection == null ? void 0 : spanSelection.resourceId) && spanSelection.resource !== "hook"
|
|
5464
|
-
),
|
|
5476
|
+
const fetchSpanDetail = reactExports.useCallback(
|
|
5477
|
+
(selection) => fetchSpanDetailResource(env, selection, {
|
|
5465
5478
|
encryptionKey: encryptionKey ?? void 0
|
|
5466
|
-
}
|
|
5479
|
+
}),
|
|
5480
|
+
[env, encryptionKey]
|
|
5467
5481
|
);
|
|
5468
5482
|
const [isDecrypting, setIsDecrypting] = reactExports.useState(false);
|
|
5469
5483
|
const handleDecrypt = reactExports.useCallback(async () => {
|
|
5470
5484
|
if (encryptionKey) {
|
|
5471
|
-
refreshSpanDetail();
|
|
5472
5485
|
return;
|
|
5473
5486
|
}
|
|
5474
5487
|
setIsDecrypting(true);
|
|
@@ -5486,18 +5499,12 @@ function RunDetailView({
|
|
|
5486
5499
|
} finally {
|
|
5487
5500
|
setIsDecrypting(false);
|
|
5488
5501
|
}
|
|
5489
|
-
}, [encryptionKey, env, runId
|
|
5490
|
-
const handleSpanSelect = reactExports.useCallback((info) => {
|
|
5491
|
-
setSpanSelection(info);
|
|
5492
|
-
}, []);
|
|
5502
|
+
}, [encryptionKey, env, runId]);
|
|
5493
5503
|
const sidebarData = reactExports.useMemo(
|
|
5494
5504
|
() => ({
|
|
5495
5505
|
run,
|
|
5496
5506
|
events: allEvents ?? [],
|
|
5497
|
-
|
|
5498
|
-
spanDetailError,
|
|
5499
|
-
spanDetailLoading,
|
|
5500
|
-
onSpanSelect: handleSpanSelect,
|
|
5507
|
+
fetchSpanDetail,
|
|
5501
5508
|
onStreamClick: handleStreamClick,
|
|
5502
5509
|
onRunClick: handleRunRefClick,
|
|
5503
5510
|
onWakeUpSleep: handleWakeUpSleep,
|
|
@@ -5511,10 +5518,7 @@ function RunDetailView({
|
|
|
5511
5518
|
[
|
|
5512
5519
|
run,
|
|
5513
5520
|
allEvents,
|
|
5514
|
-
|
|
5515
|
-
spanDetailError,
|
|
5516
|
-
spanDetailLoading,
|
|
5517
|
-
handleSpanSelect,
|
|
5521
|
+
fetchSpanDetail,
|
|
5518
5522
|
handleStreamClick,
|
|
5519
5523
|
handleRunRefClick,
|
|
5520
5524
|
handleWakeUpSleep,
|