@workflow/web-shared 5.0.0-beta.3 → 5.0.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/new-trace-viewer/components/event-list.d.ts.map +1 -1
- package/dist/components/new-trace-viewer/components/event-list.js +7 -4
- package/dist/components/new-trace-viewer/components/event-list.js.map +1 -1
- package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.d.ts +18 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.js +54 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.js.map +1 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.d.ts +20 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.js +81 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.js.map +1 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/truncate.d.ts +25 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/truncate.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/truncate.js +101 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/truncate.js.map +1 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.d.ts +20 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.js +114 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.js.map +1 -0
- package/dist/components/new-trace-viewer/components/split-pane.d.ts.map +1 -1
- package/dist/components/new-trace-viewer/components/split-pane.js +2 -3
- package/dist/components/new-trace-viewer/components/split-pane.js.map +1 -1
- package/dist/components/new-trace-viewer/components/timeline.d.ts +10 -11
- package/dist/components/new-trace-viewer/components/timeline.d.ts.map +1 -1
- package/dist/components/new-trace-viewer/components/timeline.js +57 -53
- package/dist/components/new-trace-viewer/components/timeline.js.map +1 -1
- package/dist/components/new-trace-viewer/context.d.ts.map +1 -1
- package/dist/components/new-trace-viewer/context.js +5 -7
- package/dist/components/new-trace-viewer/context.js.map +1 -1
- package/dist/components/new-trace-viewer/detail-panel.d.ts.map +1 -1
- package/dist/components/new-trace-viewer/detail-panel.js +2 -1
- package/dist/components/new-trace-viewer/detail-panel.js.map +1 -1
- package/dist/components/new-trace-viewer/trace-viewer.d.ts.map +1 -1
- package/dist/components/new-trace-viewer/trace-viewer.js +44 -18
- package/dist/components/new-trace-viewer/trace-viewer.js.map +1 -1
- package/dist/components/new-trace-viewer/utils.d.ts +3 -8
- package/dist/components/new-trace-viewer/utils.d.ts.map +1 -1
- package/dist/components/new-trace-viewer/utils.js +12 -65
- package/dist/components/new-trace-viewer/utils.js.map +1 -1
- package/dist/components/sidebar/attribute-panel.d.ts.map +1 -1
- package/dist/components/sidebar/attribute-panel.js +6 -0
- package/dist/components/sidebar/attribute-panel.js.map +1 -1
- package/dist/components/trace-viewer/util/timing.d.ts +1 -1
- package/dist/components/trace-viewer/util/timing.d.ts.map +1 -1
- package/dist/components/trace-viewer/util/timing.js +5 -8
- package/dist/components/trace-viewer/util/timing.js.map +1 -1
- package/dist/components/ui/error-stack-block.d.ts.map +1 -1
- package/dist/components/ui/error-stack-block.js +24 -2
- package/dist/components/ui/error-stack-block.js.map +1 -1
- package/dist/components/workflow-trace-view.js +1 -1
- package/dist/components/workflow-trace-view.js.map +1 -1
- package/dist/components/workflow-traces/trace-span-construction.d.ts +2 -2
- package/dist/components/workflow-traces/trace-span-construction.d.ts.map +1 -1
- package/dist/components/workflow-traces/trace-span-construction.js +17 -4
- package/dist/components/workflow-traces/trace-span-construction.js.map +1 -1
- package/dist/lib/hydration.d.ts +6 -0
- package/dist/lib/hydration.d.ts.map +1 -1
- package/dist/lib/hydration.js +124 -1
- package/dist/lib/hydration.js.map +1 -1
- package/dist/lib/trace-builder.d.ts.map +1 -1
- package/dist/lib/trace-builder.js +2 -1
- package/dist/lib/trace-builder.js.map +1 -1
- package/dist/lib/utils.d.ts +9 -7
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +27 -27
- package/dist/lib/utils.js.map +1 -1
- package/package.json +5 -4
- package/src/components/new-trace-viewer/components/event-list.tsx +26 -19
- package/src/components/new-trace-viewer/components/middle-truncate/copy-selection.ts +114 -0
- package/src/components/new-trace-viewer/components/middle-truncate/middle-truncate.tsx +157 -0
- package/src/components/new-trace-viewer/components/middle-truncate/truncate.ts +132 -0
- package/src/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.ts +167 -0
- package/src/components/new-trace-viewer/components/split-pane.tsx +2 -3
- package/src/components/new-trace-viewer/components/timeline.tsx +119 -115
- package/src/components/new-trace-viewer/context.tsx +7 -9
- package/src/components/new-trace-viewer/detail-panel.tsx +2 -1
- package/src/components/new-trace-viewer/trace-viewer.tsx +100 -32
- package/src/components/new-trace-viewer/utils.ts +19 -93
- package/src/components/sidebar/attribute-panel.tsx +5 -0
- package/src/components/trace-viewer/util/timing.ts +5 -9
- package/src/components/ui/error-stack-block.tsx +32 -4
- package/src/components/workflow-trace-view.tsx +1 -1
- package/src/components/workflow-traces/trace-span-construction.ts +23 -5
- package/src/lib/hydration.ts +132 -1
- package/src/lib/trace-builder.ts +2 -1
- package/src/lib/utils.ts +29 -29
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { parseStepName, parseWorkflowName } from '@workflow/utils/parse-name';
|
|
4
|
-
import { Search, X } from 'lucide-react';
|
|
4
|
+
import { RotateCcw, Search, X, ZoomIn, ZoomOut } from 'lucide-react';
|
|
5
5
|
import { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
|
|
6
6
|
import { ErrorBoundary } from '../error-boundary';
|
|
7
7
|
import { EntityDetailPanel, } from '../sidebar/entity-detail-panel';
|
|
8
8
|
import { useSidebarDataOptional } from '../sidebar/sidebar-data-context';
|
|
9
9
|
import { formatDuration, getHighResInMs } from '../trace-viewer/util/timing';
|
|
10
10
|
import { CopyButton } from './components/copy-button';
|
|
11
|
-
import { SplitPane } from './components/split-pane';
|
|
12
11
|
import EventList from './components/event-list';
|
|
13
|
-
import {
|
|
12
|
+
import { SplitPane } from './components/split-pane';
|
|
13
|
+
import { Timeline, TimelineHeader, TIMELINE_PADDING_PX, } from './components/timeline';
|
|
14
14
|
import { ActiveSpanProvider, useActiveSpan } from './context';
|
|
15
15
|
import { DetailPanel } from './detail-panel';
|
|
16
|
-
import {
|
|
16
|
+
import { computeRootBounds, computeTimeMarkers } from './utils';
|
|
17
17
|
const MIN_VIEWPORT_MS = 0.001;
|
|
18
|
-
const TIMELINE_PADDING = 16;
|
|
19
18
|
function useAnimatedViewport(initial) {
|
|
20
19
|
const [viewport, setViewportState] = useState(initial);
|
|
21
20
|
const animRef = useRef(null);
|
|
@@ -125,12 +124,34 @@ function NewTraceViewerContent({ trace }) {
|
|
|
125
124
|
prevRootRef.current = { start: newStart, end: newEnd };
|
|
126
125
|
}, [root.startTime, root.duration]);
|
|
127
126
|
const viewDuration = viewport.end - viewport.start;
|
|
128
|
-
const
|
|
129
|
-
const isZoomed = viewport.start > root.startTime + 0.01 ||
|
|
130
|
-
viewport.end < root.startTime + root.duration - 0.01;
|
|
127
|
+
const timeMarkers = useMemo(() => computeTimeMarkers(viewDuration, viewport.start - root.startTime), [viewDuration, viewport.start, root.startTime]);
|
|
131
128
|
const resetZoom = useCallback(() => {
|
|
132
129
|
animateTo({ start: root.startTime, end: root.startTime + root.duration });
|
|
133
130
|
}, [animateTo, root.startTime, root.duration]);
|
|
131
|
+
const ZOOM_FACTOR = 0.5;
|
|
132
|
+
const zoomBy = useCallback((factor) => {
|
|
133
|
+
const rootS = root.startTime;
|
|
134
|
+
const rootE = root.startTime + root.duration;
|
|
135
|
+
const rootD = root.duration;
|
|
136
|
+
setViewport((prev) => {
|
|
137
|
+
const prevDuration = prev.end - prev.start;
|
|
138
|
+
const center = (prev.start + prev.end) / 2;
|
|
139
|
+
const newDuration = Math.max(MIN_VIEWPORT_MS, Math.min(rootD, prevDuration * factor));
|
|
140
|
+
let newStart = center - newDuration / 2;
|
|
141
|
+
let newEnd = center + newDuration / 2;
|
|
142
|
+
if (newStart < rootS) {
|
|
143
|
+
newStart = rootS;
|
|
144
|
+
newEnd = rootS + newDuration;
|
|
145
|
+
}
|
|
146
|
+
if (newEnd > rootE) {
|
|
147
|
+
newEnd = rootE;
|
|
148
|
+
newStart = Math.max(rootS, rootE - newDuration);
|
|
149
|
+
}
|
|
150
|
+
return { start: newStart, end: newEnd };
|
|
151
|
+
});
|
|
152
|
+
}, [setViewport, root.startTime, root.duration]);
|
|
153
|
+
const zoomIn = useCallback(() => zoomBy(ZOOM_FACTOR), [zoomBy]);
|
|
154
|
+
const zoomOut = useCallback(() => zoomBy(1 / ZOOM_FACTOR), [zoomBy]);
|
|
134
155
|
const handleSelectSpan = useCallback((spanId) => {
|
|
135
156
|
if (spanId === activeSpanId) {
|
|
136
157
|
clearActiveSpan();
|
|
@@ -208,20 +229,19 @@ function NewTraceViewerContent({ trace }) {
|
|
|
208
229
|
const hoverInfo = useMemo(() => {
|
|
209
230
|
if (hoverFraction == null)
|
|
210
231
|
return null;
|
|
211
|
-
const absTime =
|
|
232
|
+
const absTime = viewport.start + hoverFraction * viewDuration;
|
|
212
233
|
const offset = absTime - root.startTime;
|
|
213
234
|
return { fraction: hoverFraction, label: formatDuration(offset, true) };
|
|
214
|
-
}, [hoverFraction,
|
|
235
|
+
}, [hoverFraction, viewport.start, viewDuration, root.startTime]);
|
|
215
236
|
const handleTimelineMouseMove = useCallback((e) => {
|
|
216
237
|
const el = timelineRef.current;
|
|
217
238
|
if (!el)
|
|
218
239
|
return;
|
|
219
240
|
const rect = el.getBoundingClientRect();
|
|
220
|
-
const
|
|
221
|
-
const contentWidth = rect.width - padding * 2;
|
|
241
|
+
const contentWidth = rect.width - TIMELINE_PADDING_PX * 2;
|
|
222
242
|
if (contentWidth <= 0)
|
|
223
243
|
return;
|
|
224
|
-
const fraction = Math.max(0, Math.min(1, (e.clientX - rect.left -
|
|
244
|
+
const fraction = Math.max(0, Math.min(1, (e.clientX - rect.left - TIMELINE_PADDING_PX) / contentWidth));
|
|
225
245
|
setHoverFraction(fraction);
|
|
226
246
|
}, []);
|
|
227
247
|
const handleTimelineMouseLeave = useCallback(() => {
|
|
@@ -243,14 +263,14 @@ function NewTraceViewerContent({ trace }) {
|
|
|
243
263
|
return;
|
|
244
264
|
e.preventDefault();
|
|
245
265
|
const rect = el.getBoundingClientRect();
|
|
246
|
-
const contentWidth = rect.width -
|
|
266
|
+
const contentWidth = rect.width - TIMELINE_PADDING_PX * 2;
|
|
247
267
|
if (contentWidth <= 0)
|
|
248
268
|
return;
|
|
249
269
|
if (isZoomGesture) {
|
|
250
270
|
let dy = e.deltaY;
|
|
251
271
|
if (e.deltaMode === 1)
|
|
252
272
|
dy *= 16;
|
|
253
|
-
const cursorFraction = Math.max(0, Math.min(1, (e.clientX - rect.left -
|
|
273
|
+
const cursorFraction = Math.max(0, Math.min(1, (e.clientX - rect.left - TIMELINE_PADDING_PX) / contentWidth));
|
|
254
274
|
const scaleFactor = Math.pow(2, dy / 200);
|
|
255
275
|
setViewport((prev) => {
|
|
256
276
|
const prevDuration = prev.end - prev.start;
|
|
@@ -298,6 +318,9 @@ function NewTraceViewerContent({ trace }) {
|
|
|
298
318
|
if (!selectedSpan?.data)
|
|
299
319
|
return 'Details';
|
|
300
320
|
const data = selectedSpan.data;
|
|
321
|
+
if (selectedSpan.resource === 'hook') {
|
|
322
|
+
return data.token ?? data.hookId;
|
|
323
|
+
}
|
|
301
324
|
const stepName = data.stepName;
|
|
302
325
|
const workflowName = data.workflowName;
|
|
303
326
|
return ((stepName ? parseStepName(stepName)?.shortName : undefined) ??
|
|
@@ -306,18 +329,21 @@ function NewTraceViewerContent({ trace }) {
|
|
|
306
329
|
workflowName ??
|
|
307
330
|
data.hookId ??
|
|
308
331
|
'Details');
|
|
309
|
-
}, [selectedSpan?.data]);
|
|
332
|
+
}, [selectedSpan?.data, selectedSpan?.resource]);
|
|
310
333
|
const selectedResource = selectedSpan?.resource;
|
|
311
334
|
const selectedResourceId = useMemo(() => {
|
|
312
335
|
if (!selectedSpan?.data)
|
|
313
336
|
return undefined;
|
|
314
337
|
const data = selectedSpan.data;
|
|
338
|
+
if (selectedSpan.resource === 'hook') {
|
|
339
|
+
return data.hookId ?? selectedSpan.spanId;
|
|
340
|
+
}
|
|
315
341
|
return (data.stepId ??
|
|
316
342
|
data.runId ??
|
|
317
343
|
data.hookId ??
|
|
318
344
|
selectedSpan.spanId);
|
|
319
|
-
}, [selectedSpan?.data, selectedSpan?.spanId]);
|
|
320
|
-
return (_jsxs("div", { "data-pane": "pane-root", "data-has-detail": activeSpan ? '' : undefined, className: "grid w-full h-full max-h-full grid-cols-[minmax(100px,1fr)] data-[has-detail]:grid-cols-[minmax(100px,1fr)_clamp(280px,420px,100%)]", children: [
|
|
345
|
+
}, [selectedSpan?.data, selectedSpan?.resource, selectedSpan?.spanId]);
|
|
346
|
+
return (_jsxs("div", { "data-pane": "pane-root", "data-has-detail": activeSpan ? '' : undefined, className: "grid w-full h-full max-h-full grid-cols-[minmax(100px,1fr)] data-[has-detail]:grid-cols-[minmax(100px,1fr)_clamp(280px,420px,100%)]", children: [_jsxs("div", { id: "trace-parent", className: "grid grid-rows-[1fr] h-full min-h-0 overflow-hidden relative bg-background-100", children: [_jsxs(SplitPane, { startHeader: _jsxs("div", { className: "bg-background-100 border-b border-gray-alpha-400 h-10 min-h-10 flex items-center px-2 gap-1.5", children: [_jsx(Search, { className: "w-3.5 h-3.5 shrink-0 text-gray-800" }), _jsx("input", { id: "trace-viewer-search", name: "trace-viewer-search", type: "text", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), 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 && (_jsx("button", { type: "button", onClick: () => setSearchQuery(''), className: "shrink-0 p-0.5 rounded-sm text-gray-800 hover:text-gray-1000 hover:bg-gray-200 transition-colors", children: _jsx(X, { className: "w-3 h-3" }) }))] }), endHeader: _jsx(TimelineHeader, { markers: timeMarkers, hoverInfo: hoverInfo }), children: [_jsx("div", { className: "block overflow-visible", children: _jsx(EventList, { spans: filteredSpans, activeSpanId: activeSpanId, onSelectSpan: handleSelectSpan }) }), _jsx("div", { ref: timelineRef, className: "block min-h-0 overflow-visible relative", onDoubleClick: resetZoom, onMouseMove: handleTimelineMouseMove, onMouseLeave: handleTimelineMouseLeave, children: _jsx(Timeline, { spans: filteredSpans, viewStart: viewport.start, viewEnd: viewport.end, markers: timeMarkers, selectedId: activeSpanId, onSelect: handleSelectSpan, hoverFraction: hoverFraction, altHeld: altHeld }) })] }), _jsxs("div", { className: "absolute right-3 bottom-3 z-[5] flex items-center border border-gray-alpha-400 rounded-lg bg-background-100 shadow-sm overflow-hidden divide-x divide-gray-alpha-400", children: [_jsx("button", { type: "button", className: "flex items-center justify-center w-8 h-8 text-gray-900 cursor-pointer transition-colors duration-[120ms] ease-in-out hover:text-gray-1000 hover:bg-gray-alpha-100", onClick: zoomOut, "aria-label": "Zoom out", children: _jsx(ZoomOut, { className: "w-4 h-4" }) }), _jsx("button", { type: "button", className: "flex items-center justify-center w-8 h-8 text-gray-900 cursor-pointer transition-colors duration-[120ms] ease-in-out hover:text-gray-1000 hover:bg-gray-alpha-100", onClick: resetZoom, "aria-label": "Reset zoom", children: _jsx(RotateCcw, { className: "w-3.5 h-3.5" }) }), _jsx("button", { type: "button", className: "flex items-center justify-center w-8 h-8 text-gray-900 cursor-pointer transition-colors duration-[120ms] ease-in-out hover:text-gray-1000 hover:bg-gray-alpha-100", onClick: zoomIn, "aria-label": "Zoom in", children: _jsx(ZoomIn, { className: "w-4 h-4" }) })] })] }), activeSpan && sidebar ? (_jsxs("aside", { className: "flex flex-col h-full max-h-full bg-background-100 border-l border-gray-alpha-400 overflow-auto", children: [_jsx("div", { className: "flex-shrink-0 px-4 pt-4 pb-3", children: _jsxs("div", { className: "flex items-start justify-between gap-2", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "text-[15px] font-semibold text-gray-1000 truncate block", children: selectedSpanName }), selectedResourceId && (_jsxs("div", { className: "mt-1 flex items-center gap-2", children: [selectedResource && (_jsx("span", { className: `inline-flex items-center rounded-md px-1.5 py-0.5 text-[11px] font-medium leading-none shrink-0 ${selectedResource === 'step'
|
|
321
347
|
? 'bg-green-200 text-green-900'
|
|
322
348
|
: selectedResource === 'run'
|
|
323
349
|
? 'bg-blue-200 text-blue-900'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trace-viewer.js","sourceRoot":"","sources":["../../../src/components/new-trace-viewer/trace-viewer.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport { parseStepName, parseWorkflowName } from '@workflow/utils/parse-name';\nimport { Search, X } from 'lucide-react';\nimport {\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { ErrorBoundary } from '../error-boundary';\nimport {\n EntityDetailPanel,\n type SelectedSpanInfo,\n} from '../sidebar/entity-detail-panel';\nimport { useSidebarDataOptional } from '../sidebar/sidebar-data-context';\nimport type { Trace } from '../trace-viewer/types';\nimport { formatDuration, getHighResInMs } from '../trace-viewer/util/timing';\nimport { CopyButton } from './components/copy-button';\nimport { SplitPane } from './components/split-pane';\nimport EventList from './components/event-list';\nimport { Timeline, TimelineHeader } from './components/timeline';\nimport { ActiveSpanProvider, useActiveSpan } from './context';\nimport { DetailPanel } from './detail-panel';\nimport { buildTimeCompression, computeRootBounds } from './utils';\n\ninterface NewTraceViewerProps {\n trace: Trace;\n}\n\nconst MIN_VIEWPORT_MS = 0.001;\nconst TIMELINE_PADDING = 16;\n\ninterface Viewport {\n start: number;\n end: number;\n}\n\nfunction useAnimatedViewport(initial: Viewport) {\n const [viewport, setViewportState] = useState<Viewport>(initial);\n const animRef = useRef<{\n raf: number;\n from: Viewport;\n to: Viewport;\n start: number;\n } | null>(null);\n const currentRef = useRef(initial);\n currentRef.current = viewport;\n\n const cancel = useCallback(() => {\n if (animRef.current) {\n cancelAnimationFrame(animRef.current.raf);\n animRef.current = null;\n }\n }, []);\n\n const animateTo = useCallback(\n (target: Viewport) => {\n cancel();\n const from = currentRef.current;\n const anim = { raf: 0, from, to: target, start: performance.now() };\n\n const tick = () => {\n const t = Math.min((performance.now() - anim.start) / 150, 1);\n const e = 1 - (1 - t) * (1 - t);\n setViewportState({\n start: anim.from.start + (anim.to.start - anim.from.start) * e,\n end: anim.from.end + (anim.to.end - anim.from.end) * e,\n });\n if (t < 1) anim.raf = requestAnimationFrame(tick);\n else animRef.current = null;\n };\n\n animRef.current = anim;\n anim.raf = requestAnimationFrame(tick);\n },\n [cancel]\n );\n\n const setViewport = useCallback(\n (update: Viewport | ((prev: Viewport) => Viewport)) => {\n cancel();\n if (typeof update === 'function') {\n setViewportState((prev) => {\n const next = update(prev);\n currentRef.current = next;\n return next;\n });\n } else {\n currentRef.current = update;\n setViewportState(update);\n }\n },\n [cancel]\n );\n\n useEffect(() => cancel, [cancel]);\n\n return { viewport, setViewport, animateTo };\n}\n\n// ---------------------------------------------------------------------------\n// Hook: bridge ActiveSpanContext + SidebarDataContext → SelectedSpanInfo\n// ---------------------------------------------------------------------------\n\nfunction useSelectedSpanInfo(): SelectedSpanInfo | null {\n const { activeSpan } = useActiveSpan();\n const sidebar = useSidebarDataOptional();\n\n return useMemo(() => {\n if (!activeSpan || !sidebar) return null;\n\n const correlationId = activeSpan.spanId;\n const rawEvents = correlationId\n ? sidebar.events.filter((e) => e.correlationId === correlationId)\n : [];\n\n return {\n data: activeSpan.attributes?.data,\n resource: activeSpan.attributes?.resource as string | undefined,\n spanId: activeSpan.spanId,\n rawEvents,\n };\n }, [activeSpan, sidebar?.events]);\n}\n\n// ---------------------------------------------------------------------------\n// Root component\n// ---------------------------------------------------------------------------\n\nexport function NewTraceViewer({ trace }: NewTraceViewerProps): ReactNode {\n return (\n <ActiveSpanProvider spans={trace.spans}>\n <NewTraceViewerContent trace={trace} />\n </ActiveSpanProvider>\n );\n}\n\nfunction NewTraceViewerContent({ trace }: NewTraceViewerProps): ReactNode {\n const { activeSpan, activeSpanId, setActiveSpan, clearActiveSpan } =\n useActiveSpan();\n\n const sidebar = useSidebarDataOptional();\n const selectedSpan = useSelectedSpanInfo();\n\n const [searchQuery, setSearchQuery] = useState('');\n\n const filteredSpans = useMemo(() => {\n const q = searchQuery.trim().toLowerCase();\n if (!q) return trace.spans;\n return trace.spans.filter(\n (s) =>\n s.name.toLowerCase().includes(q) || s.resource.toLowerCase().includes(q)\n );\n }, [trace.spans, searchQuery]);\n\n const root = useMemo(() => computeRootBounds(trace.spans), [trace.spans]);\n\n const { viewport, setViewport, animateTo } = useAnimatedViewport({\n start: root.startTime,\n end: root.startTime + root.duration,\n });\n\n const prevRootRef = useRef<Viewport>({\n start: root.startTime,\n end: root.startTime + root.duration,\n });\n\n useEffect(() => {\n const prevRoot = prevRootRef.current;\n const newStart = root.startTime;\n const newEnd = root.startTime + root.duration;\n\n setViewport((prev) => {\n const wasAtFullExtent =\n Math.abs(prev.start - prevRoot.start) < 0.01 &&\n Math.abs(prev.end - prevRoot.end) < 0.01;\n\n if (wasAtFullExtent) {\n return { start: newStart, end: newEnd };\n }\n return prev;\n });\n\n prevRootRef.current = { start: newStart, end: newEnd };\n }, [root.startTime, root.duration]);\n\n const viewDuration = viewport.end - viewport.start;\n\n const compression = useMemo(\n () => buildTimeCompression(trace.spans, viewport.start, viewport.end),\n [trace.spans, viewport.start, viewport.end]\n );\n\n const isZoomed =\n viewport.start > root.startTime + 0.01 ||\n viewport.end < root.startTime + root.duration - 0.01;\n\n const resetZoom = useCallback(() => {\n animateTo({ start: root.startTime, end: root.startTime + root.duration });\n }, [animateTo, root.startTime, root.duration]);\n\n const handleSelectSpan = useCallback(\n (spanId: string) => {\n if (spanId === activeSpanId) {\n clearActiveSpan();\n return;\n }\n setActiveSpan(spanId);\n\n const span = trace.spans.find((s) => s.spanId === spanId);\n if (!span) return;\n\n const spanStart = getHighResInMs(span.startTime);\n const spanEnd = getHighResInMs(span.endTime);\n const spanDuration = spanEnd - spanStart;\n\n const rootS = root.startTime;\n const rootE = root.startTime + root.duration;\n const rootD = root.duration;\n\n if (spanDuration > rootD * 0.8) {\n animateTo({ start: rootS, end: rootE });\n return;\n }\n\n const padding = Math.max(spanDuration * 0.2, MIN_VIEWPORT_MS / 2);\n let newStart = spanStart - padding;\n let newEnd = spanEnd + padding;\n\n if (newEnd - newStart < MIN_VIEWPORT_MS) {\n const center = (spanStart + spanEnd) / 2;\n newStart = center - MIN_VIEWPORT_MS / 2;\n newEnd = center + MIN_VIEWPORT_MS / 2;\n }\n\n if (newStart < rootS) {\n const duration = newEnd - newStart;\n newStart = rootS;\n newEnd = Math.min(rootE, rootS + duration);\n }\n if (newEnd > rootE) {\n const duration = newEnd - newStart;\n newEnd = rootE;\n newStart = Math.max(rootS, rootE - duration);\n }\n\n animateTo({ start: newStart, end: newEnd });\n },\n [\n animateTo,\n setActiveSpan,\n clearActiveSpan,\n activeSpanId,\n trace.spans,\n root.startTime,\n root.duration,\n ]\n );\n\n const [altHeld, setAltHeld] = useState(false);\n\n useEffect(() => {\n const onKeyDown = (e: KeyboardEvent): void => {\n if (e.key === 'Escape') {\n clearActiveSpan();\n }\n if (e.key === 'Alt') {\n e.preventDefault();\n setAltHeld(true);\n }\n };\n const onKeyUp = (e: KeyboardEvent): void => {\n if (e.key === 'Alt') setAltHeld(false);\n };\n const onBlur = (): void => setAltHeld(false);\n\n window.addEventListener('keydown', onKeyDown);\n window.addEventListener('keyup', onKeyUp);\n window.addEventListener('blur', onBlur);\n return () => {\n window.removeEventListener('keydown', onKeyDown);\n window.removeEventListener('keyup', onKeyUp);\n window.removeEventListener('blur', onBlur);\n };\n }, [clearActiveSpan]);\n\n const timelineRef = useRef<HTMLDivElement>(null);\n const [hoverFraction, setHoverFraction] = useState<number | null>(null);\n\n const hoverInfo = useMemo(() => {\n if (hoverFraction == null) return null;\n const absTime = compression.fromVisual(hoverFraction);\n const offset = absTime - root.startTime;\n return { fraction: hoverFraction, label: formatDuration(offset, true) };\n }, [hoverFraction, compression, root.startTime]);\n\n const handleTimelineMouseMove = useCallback(\n (e: React.MouseEvent<HTMLDivElement>) => {\n const el = timelineRef.current;\n if (!el) return;\n const rect = el.getBoundingClientRect();\n const padding = 8;\n const contentWidth = rect.width - padding * 2;\n if (contentWidth <= 0) return;\n const fraction = Math.max(\n 0,\n Math.min(1, (e.clientX - rect.left - padding) / contentWidth)\n );\n setHoverFraction(fraction);\n },\n []\n );\n\n const handleTimelineMouseLeave = useCallback(() => {\n setHoverFraction(null);\n }, []);\n\n useEffect(() => {\n const el = timelineRef.current;\n if (!el) return;\n\n const rootS = root.startTime;\n const rootE = root.startTime + root.duration;\n const rootD = root.duration;\n if (rootD <= 0) return;\n\n const onWheel = (e: WheelEvent): void => {\n const isZoomGesture = e.ctrlKey || e.metaKey;\n const hasDeltaX = Math.abs(e.deltaX) > Math.abs(e.deltaY);\n\n if (!isZoomGesture && !hasDeltaX) return;\n e.preventDefault();\n\n const rect = el.getBoundingClientRect();\n const contentWidth = rect.width - TIMELINE_PADDING * 2;\n if (contentWidth <= 0) return;\n\n if (isZoomGesture) {\n let dy = e.deltaY;\n if (e.deltaMode === 1) dy *= 16;\n\n const cursorFraction = Math.max(\n 0,\n Math.min(1, (e.clientX - rect.left - TIMELINE_PADDING) / contentWidth)\n );\n const scaleFactor = Math.pow(2, dy / 200);\n\n setViewport((prev) => {\n const prevDuration = prev.end - prev.start;\n const cursorTime = prev.start + cursorFraction * prevDuration;\n const newDuration = Math.max(\n MIN_VIEWPORT_MS,\n Math.min(rootD, prevDuration * scaleFactor)\n );\n\n let newStart = cursorTime - cursorFraction * newDuration;\n let newEnd = newStart + newDuration;\n\n if (newStart < rootS) {\n newStart = rootS;\n newEnd = rootS + newDuration;\n }\n if (newEnd > rootE) {\n newEnd = rootE;\n newStart = Math.max(rootS, rootE - newDuration);\n }\n\n return { start: newStart, end: newEnd };\n });\n } else {\n let dx = e.deltaX;\n if (e.deltaMode === 1) dx *= 16;\n\n setViewport((prev) => {\n const prevDuration = prev.end - prev.start;\n const panAmount = (dx / contentWidth) * prevDuration;\n\n let newStart = prev.start + panAmount;\n let newEnd = prev.end + panAmount;\n\n if (newStart < rootS) {\n newStart = rootS;\n newEnd = rootS + prevDuration;\n }\n if (newEnd > rootE) {\n newEnd = rootE;\n newStart = Math.max(rootS, rootE - prevDuration);\n }\n\n return { start: newStart, end: newEnd };\n });\n }\n };\n\n el.addEventListener('wheel', onWheel, { passive: false });\n return () => el.removeEventListener('wheel', onWheel);\n }, [root.startTime, root.duration]);\n\n // Derive the selected span name and metadata for the panel header\n const selectedSpanName = useMemo(() => {\n if (!selectedSpan?.data) return 'Details';\n const data = selectedSpan.data as Record<string, unknown>;\n const stepName = data.stepName as string | undefined;\n const workflowName = data.workflowName as string | undefined;\n return (\n (stepName ? parseStepName(stepName)?.shortName : undefined) ??\n (workflowName ? parseWorkflowName(workflowName)?.shortName : undefined) ??\n stepName ??\n workflowName ??\n (data.hookId as string) ??\n 'Details'\n );\n }, [selectedSpan?.data]);\n\n const selectedResource = selectedSpan?.resource as string | undefined;\n const selectedResourceId = useMemo(() => {\n if (!selectedSpan?.data) return undefined;\n const data = selectedSpan.data as Record<string, unknown>;\n return (\n (data.stepId as string) ??\n (data.runId as string) ??\n (data.hookId as string) ??\n selectedSpan.spanId\n );\n }, [selectedSpan?.data, selectedSpan?.spanId]);\n\n return (\n <div\n data-pane=\"pane-root\"\n data-has-detail={activeSpan ? '' : undefined}\n className=\"grid w-full h-full max-h-full grid-cols-[minmax(100px,1fr)] data-[has-detail]:grid-cols-[minmax(100px,1fr)_clamp(280px,420px,100%)]\"\n >\n <div\n id=\"trace-parent\"\n className=\"grid grid-rows-[1fr] h-full min-h-0 overflow-hidden relative bg-background-100\"\n >\n <SplitPane\n startHeader={\n <div className=\"bg-background-100 border-b border-gray-alpha-400 h-10 min-h-10 flex items-center px-2 gap-1.5\">\n <Search className=\"w-3.5 h-3.5 shrink-0 text-gray-800\" />\n <input\n id=\"trace-viewer-search\"\n name=\"trace-viewer-search\"\n type=\"text\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n placeholder=\"Search spans...\"\n aria-label=\"Search spans\"\n className=\"flex-1 min-w-0 bg-transparent text-sm text-gray-1000 placeholder:text-gray-800 outline-none\"\n />\n {searchQuery && (\n <button\n type=\"button\"\n onClick={() => setSearchQuery('')}\n className=\"shrink-0 p-0.5 rounded-sm text-gray-800 hover:text-gray-1000 hover:bg-gray-200 transition-colors\"\n >\n <X className=\"w-3 h-3\" />\n </button>\n )}\n </div>\n }\n endHeader={\n <TimelineHeader\n viewStart={viewport.start}\n viewDuration={viewDuration}\n rootStart={root.startTime}\n compression={compression}\n isZoomed={isZoomed}\n onResetZoom={resetZoom}\n hoverInfo={hoverInfo}\n />\n }\n >\n <div className=\"block overflow-visible\">\n <EventList\n spans={filteredSpans}\n activeSpanId={activeSpanId}\n onSelectSpan={handleSelectSpan}\n />\n </div>\n <div\n ref={timelineRef}\n className=\"block min-h-0 overflow-visible relative px-2\"\n onDoubleClick={resetZoom}\n onMouseMove={handleTimelineMouseMove}\n onMouseLeave={handleTimelineMouseLeave}\n >\n <Timeline\n spans={filteredSpans}\n compression={compression}\n selectedId={activeSpanId}\n onSelect={handleSelectSpan}\n hoverFraction={hoverFraction}\n altHeld={altHeld}\n />\n </div>\n </SplitPane>\n </div>\n\n {/* Detail panel */}\n {activeSpan && sidebar ? (\n <aside className=\"flex flex-col h-full max-h-full bg-background-100 border-l border-gray-alpha-400 overflow-auto\">\n {/* Panel header */}\n <div className=\"flex-shrink-0 px-4 pt-4 pb-3\">\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"min-w-0 flex-1\">\n <span className=\"text-[15px] font-semibold text-gray-1000 truncate block\">\n {selectedSpanName}\n </span>\n {selectedResourceId && (\n <div className=\"mt-1 flex items-center gap-2\">\n {selectedResource && (\n <span\n className={`inline-flex items-center rounded-md px-1.5 py-0.5 text-[11px] font-medium leading-none shrink-0 ${\n selectedResource === 'step'\n ? 'bg-green-200 text-green-900'\n : selectedResource === 'run'\n ? 'bg-blue-200 text-blue-900'\n : selectedResource === 'hook'\n ? 'bg-yellow-200 text-yellow-900'\n : 'bg-gray-200 text-gray-900'\n }`}\n >\n {selectedResource.charAt(0).toUpperCase() +\n selectedResource.slice(1)}\n </span>\n )}\n <div\n className=\"flex items-center gap-1 text-[13px] font-mono text-gray-700 min-w-0\"\n title={selectedResourceId}\n >\n <span className=\"truncate\">{selectedResourceId}</span>\n <CopyButton\n copyText={selectedResourceId}\n ariaLabel=\"Copy ID\"\n className=\"shrink-0\"\n />\n </div>\n </div>\n )}\n </div>\n <button\n type=\"button\"\n className=\"p-1 rounded-md text-gray-900 hover:text-gray-1000 hover:bg-gray-alpha-200 transition-colors shrink-0\"\n onClick={clearActiveSpan}\n >\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n {/* Panel body */}\n <div className=\"flex-1 overflow-y-auto\">\n <ErrorBoundary>\n <EntityDetailPanel\n run={sidebar.run}\n onStreamClick={sidebar.onStreamClick}\n onRunClick={sidebar.onRunClick}\n spanDetailData={sidebar.spanDetailData}\n spanDetailError={sidebar.spanDetailError}\n spanDetailLoading={sidebar.spanDetailLoading}\n onSpanSelect={sidebar.onSpanSelect}\n onWakeUpSleep={sidebar.onWakeUpSleep}\n onLoadEventData={sidebar.onLoadEventData}\n onResolveHook={sidebar.onResolveHook}\n encryptionKey={sidebar.encryptionKey}\n onDecrypt={sidebar.onDecrypt}\n isDecrypting={sidebar.isDecrypting}\n selectedSpan={selectedSpan}\n />\n </ErrorBoundary>\n </div>\n </aside>\n ) : activeSpan ? (\n <DetailPanel\n span={activeSpan}\n rootStart={root.startTime}\n onClose={clearActiveSpan}\n />\n ) : null}\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"trace-viewer.js","sourceRoot":"","sources":["../../../src/components/new-trace-viewer/trace-viewer.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport { parseStepName, parseWorkflowName } from '@workflow/utils/parse-name';\nimport { RotateCcw, Search, X, ZoomIn, ZoomOut } from 'lucide-react';\nimport {\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { ErrorBoundary } from '../error-boundary';\nimport {\n EntityDetailPanel,\n type SelectedSpanInfo,\n} from '../sidebar/entity-detail-panel';\nimport { useSidebarDataOptional } from '../sidebar/sidebar-data-context';\nimport type { Trace } from '../trace-viewer/types';\nimport { formatDuration, getHighResInMs } from '../trace-viewer/util/timing';\nimport { CopyButton } from './components/copy-button';\nimport EventList from './components/event-list';\nimport { SplitPane } from './components/split-pane';\nimport {\n Timeline,\n TimelineHeader,\n TIMELINE_PADDING_PX,\n} from './components/timeline';\nimport { ActiveSpanProvider, useActiveSpan } from './context';\nimport { DetailPanel } from './detail-panel';\nimport { computeRootBounds, computeTimeMarkers } from './utils';\n\ninterface NewTraceViewerProps {\n trace: Trace;\n}\n\nconst MIN_VIEWPORT_MS = 0.001;\n\ninterface Viewport {\n start: number;\n end: number;\n}\n\nfunction useAnimatedViewport(initial: Viewport) {\n const [viewport, setViewportState] = useState<Viewport>(initial);\n const animRef = useRef<{\n raf: number;\n from: Viewport;\n to: Viewport;\n start: number;\n } | null>(null);\n const currentRef = useRef(initial);\n currentRef.current = viewport;\n\n const cancel = useCallback(() => {\n if (animRef.current) {\n cancelAnimationFrame(animRef.current.raf);\n animRef.current = null;\n }\n }, []);\n\n const animateTo = useCallback(\n (target: Viewport) => {\n cancel();\n const from = currentRef.current;\n const anim = { raf: 0, from, to: target, start: performance.now() };\n\n const tick = () => {\n const t = Math.min((performance.now() - anim.start) / 150, 1);\n const e = 1 - (1 - t) * (1 - t);\n setViewportState({\n start: anim.from.start + (anim.to.start - anim.from.start) * e,\n end: anim.from.end + (anim.to.end - anim.from.end) * e,\n });\n if (t < 1) anim.raf = requestAnimationFrame(tick);\n else animRef.current = null;\n };\n\n animRef.current = anim;\n anim.raf = requestAnimationFrame(tick);\n },\n [cancel]\n );\n\n const setViewport = useCallback(\n (update: Viewport | ((prev: Viewport) => Viewport)) => {\n cancel();\n if (typeof update === 'function') {\n setViewportState((prev) => {\n const next = update(prev);\n currentRef.current = next;\n return next;\n });\n } else {\n currentRef.current = update;\n setViewportState(update);\n }\n },\n [cancel]\n );\n\n useEffect(() => cancel, [cancel]);\n\n return { viewport, setViewport, animateTo };\n}\n\n// ---------------------------------------------------------------------------\n// Hook: bridge ActiveSpanContext + SidebarDataContext → SelectedSpanInfo\n// ---------------------------------------------------------------------------\n\nfunction useSelectedSpanInfo(): SelectedSpanInfo | null {\n const { activeSpan } = useActiveSpan();\n const sidebar = useSidebarDataOptional();\n\n return useMemo(() => {\n if (!activeSpan || !sidebar) return null;\n\n const correlationId = activeSpan.spanId;\n const rawEvents = correlationId\n ? sidebar.events.filter((e) => e.correlationId === correlationId)\n : [];\n\n return {\n data: activeSpan.attributes?.data,\n resource: activeSpan.attributes?.resource as string | undefined,\n spanId: activeSpan.spanId,\n rawEvents,\n };\n }, [activeSpan, sidebar?.events]);\n}\n\n// ---------------------------------------------------------------------------\n// Root component\n// ---------------------------------------------------------------------------\n\nexport function NewTraceViewer({ trace }: NewTraceViewerProps): ReactNode {\n return (\n <ActiveSpanProvider spans={trace.spans}>\n <NewTraceViewerContent trace={trace} />\n </ActiveSpanProvider>\n );\n}\n\nfunction NewTraceViewerContent({ trace }: NewTraceViewerProps): ReactNode {\n const { activeSpan, activeSpanId, setActiveSpan, clearActiveSpan } =\n useActiveSpan();\n\n const sidebar = useSidebarDataOptional();\n const selectedSpan = useSelectedSpanInfo();\n\n const [searchQuery, setSearchQuery] = useState('');\n\n const filteredSpans = useMemo(() => {\n const q = searchQuery.trim().toLowerCase();\n if (!q) return trace.spans;\n return trace.spans.filter(\n (s) =>\n s.name.toLowerCase().includes(q) || s.resource.toLowerCase().includes(q)\n );\n }, [trace.spans, searchQuery]);\n\n const root = useMemo(() => computeRootBounds(trace.spans), [trace.spans]);\n\n const { viewport, setViewport, animateTo } = useAnimatedViewport({\n start: root.startTime,\n end: root.startTime + root.duration,\n });\n\n const prevRootRef = useRef<Viewport>({\n start: root.startTime,\n end: root.startTime + root.duration,\n });\n\n useEffect(() => {\n const prevRoot = prevRootRef.current;\n const newStart = root.startTime;\n const newEnd = root.startTime + root.duration;\n\n setViewport((prev) => {\n const wasAtFullExtent =\n Math.abs(prev.start - prevRoot.start) < 0.01 &&\n Math.abs(prev.end - prevRoot.end) < 0.01;\n\n if (wasAtFullExtent) {\n return { start: newStart, end: newEnd };\n }\n return prev;\n });\n\n prevRootRef.current = { start: newStart, end: newEnd };\n }, [root.startTime, root.duration]);\n\n const viewDuration = viewport.end - viewport.start;\n\n const timeMarkers = useMemo(\n () => computeTimeMarkers(viewDuration, viewport.start - root.startTime),\n [viewDuration, viewport.start, root.startTime]\n );\n\n const resetZoom = useCallback(() => {\n animateTo({ start: root.startTime, end: root.startTime + root.duration });\n }, [animateTo, root.startTime, root.duration]);\n\n const ZOOM_FACTOR = 0.5;\n\n const zoomBy = useCallback(\n (factor: number) => {\n const rootS = root.startTime;\n const rootE = root.startTime + root.duration;\n const rootD = root.duration;\n\n setViewport((prev) => {\n const prevDuration = prev.end - prev.start;\n const center = (prev.start + prev.end) / 2;\n const newDuration = Math.max(\n MIN_VIEWPORT_MS,\n Math.min(rootD, prevDuration * factor)\n );\n let newStart = center - newDuration / 2;\n let newEnd = center + newDuration / 2;\n\n if (newStart < rootS) {\n newStart = rootS;\n newEnd = rootS + newDuration;\n }\n if (newEnd > rootE) {\n newEnd = rootE;\n newStart = Math.max(rootS, rootE - newDuration);\n }\n\n return { start: newStart, end: newEnd };\n });\n },\n [setViewport, root.startTime, root.duration]\n );\n\n const zoomIn = useCallback(() => zoomBy(ZOOM_FACTOR), [zoomBy]);\n const zoomOut = useCallback(() => zoomBy(1 / ZOOM_FACTOR), [zoomBy]);\n\n const handleSelectSpan = useCallback(\n (spanId: string) => {\n if (spanId === activeSpanId) {\n clearActiveSpan();\n return;\n }\n setActiveSpan(spanId);\n\n const span = trace.spans.find((s) => s.spanId === spanId);\n if (!span) return;\n\n const spanStart = getHighResInMs(span.startTime);\n const spanEnd = getHighResInMs(span.endTime);\n const spanDuration = spanEnd - spanStart;\n\n const rootS = root.startTime;\n const rootE = root.startTime + root.duration;\n const rootD = root.duration;\n\n if (spanDuration > rootD * 0.8) {\n animateTo({ start: rootS, end: rootE });\n return;\n }\n\n const padding = Math.max(spanDuration * 0.2, MIN_VIEWPORT_MS / 2);\n let newStart = spanStart - padding;\n let newEnd = spanEnd + padding;\n\n if (newEnd - newStart < MIN_VIEWPORT_MS) {\n const center = (spanStart + spanEnd) / 2;\n newStart = center - MIN_VIEWPORT_MS / 2;\n newEnd = center + MIN_VIEWPORT_MS / 2;\n }\n\n if (newStart < rootS) {\n const duration = newEnd - newStart;\n newStart = rootS;\n newEnd = Math.min(rootE, rootS + duration);\n }\n if (newEnd > rootE) {\n const duration = newEnd - newStart;\n newEnd = rootE;\n newStart = Math.max(rootS, rootE - duration);\n }\n\n animateTo({ start: newStart, end: newEnd });\n },\n [\n animateTo,\n setActiveSpan,\n clearActiveSpan,\n activeSpanId,\n trace.spans,\n root.startTime,\n root.duration,\n ]\n );\n\n const [altHeld, setAltHeld] = useState(false);\n\n useEffect(() => {\n const onKeyDown = (e: KeyboardEvent): void => {\n if (e.key === 'Escape') {\n clearActiveSpan();\n }\n if (e.key === 'Alt') {\n e.preventDefault();\n setAltHeld(true);\n }\n };\n const onKeyUp = (e: KeyboardEvent): void => {\n if (e.key === 'Alt') setAltHeld(false);\n };\n const onBlur = (): void => setAltHeld(false);\n\n window.addEventListener('keydown', onKeyDown);\n window.addEventListener('keyup', onKeyUp);\n window.addEventListener('blur', onBlur);\n return () => {\n window.removeEventListener('keydown', onKeyDown);\n window.removeEventListener('keyup', onKeyUp);\n window.removeEventListener('blur', onBlur);\n };\n }, [clearActiveSpan]);\n\n const timelineRef = useRef<HTMLDivElement>(null);\n const [hoverFraction, setHoverFraction] = useState<number | null>(null);\n\n const hoverInfo = useMemo(() => {\n if (hoverFraction == null) return null;\n const absTime = viewport.start + hoverFraction * viewDuration;\n const offset = absTime - root.startTime;\n return { fraction: hoverFraction, label: formatDuration(offset, true) };\n }, [hoverFraction, viewport.start, viewDuration, root.startTime]);\n\n const handleTimelineMouseMove = useCallback(\n (e: React.MouseEvent<HTMLDivElement>) => {\n const el = timelineRef.current;\n if (!el) return;\n const rect = el.getBoundingClientRect();\n const contentWidth = rect.width - TIMELINE_PADDING_PX * 2;\n if (contentWidth <= 0) return;\n const fraction = Math.max(\n 0,\n Math.min(\n 1,\n (e.clientX - rect.left - TIMELINE_PADDING_PX) / contentWidth\n )\n );\n setHoverFraction(fraction);\n },\n []\n );\n\n const handleTimelineMouseLeave = useCallback(() => {\n setHoverFraction(null);\n }, []);\n\n useEffect(() => {\n const el = timelineRef.current;\n if (!el) return;\n\n const rootS = root.startTime;\n const rootE = root.startTime + root.duration;\n const rootD = root.duration;\n if (rootD <= 0) return;\n\n const onWheel = (e: WheelEvent): void => {\n const isZoomGesture = e.ctrlKey || e.metaKey;\n const hasDeltaX = Math.abs(e.deltaX) > Math.abs(e.deltaY);\n\n if (!isZoomGesture && !hasDeltaX) return;\n e.preventDefault();\n\n const rect = el.getBoundingClientRect();\n const contentWidth = rect.width - TIMELINE_PADDING_PX * 2;\n if (contentWidth <= 0) return;\n\n if (isZoomGesture) {\n let dy = e.deltaY;\n if (e.deltaMode === 1) dy *= 16;\n\n const cursorFraction = Math.max(\n 0,\n Math.min(\n 1,\n (e.clientX - rect.left - TIMELINE_PADDING_PX) / contentWidth\n )\n );\n const scaleFactor = Math.pow(2, dy / 200);\n\n setViewport((prev) => {\n const prevDuration = prev.end - prev.start;\n const cursorTime = prev.start + cursorFraction * prevDuration;\n const newDuration = Math.max(\n MIN_VIEWPORT_MS,\n Math.min(rootD, prevDuration * scaleFactor)\n );\n\n let newStart = cursorTime - cursorFraction * newDuration;\n let newEnd = newStart + newDuration;\n\n if (newStart < rootS) {\n newStart = rootS;\n newEnd = rootS + newDuration;\n }\n if (newEnd > rootE) {\n newEnd = rootE;\n newStart = Math.max(rootS, rootE - newDuration);\n }\n\n return { start: newStart, end: newEnd };\n });\n } else {\n let dx = e.deltaX;\n if (e.deltaMode === 1) dx *= 16;\n\n setViewport((prev) => {\n const prevDuration = prev.end - prev.start;\n const panAmount = (dx / contentWidth) * prevDuration;\n\n let newStart = prev.start + panAmount;\n let newEnd = prev.end + panAmount;\n\n if (newStart < rootS) {\n newStart = rootS;\n newEnd = rootS + prevDuration;\n }\n if (newEnd > rootE) {\n newEnd = rootE;\n newStart = Math.max(rootS, rootE - prevDuration);\n }\n\n return { start: newStart, end: newEnd };\n });\n }\n };\n\n el.addEventListener('wheel', onWheel, { passive: false });\n return () => el.removeEventListener('wheel', onWheel);\n }, [root.startTime, root.duration]);\n\n // Derive the selected span name and metadata for the panel header\n const selectedSpanName = useMemo(() => {\n if (!selectedSpan?.data) return 'Details';\n const data = selectedSpan.data as Record<string, unknown>;\n if (selectedSpan.resource === 'hook') {\n return (data.token as string | undefined) ?? (data.hookId as string);\n }\n\n const stepName = data.stepName as string | undefined;\n const workflowName = data.workflowName as string | undefined;\n return (\n (stepName ? parseStepName(stepName)?.shortName : undefined) ??\n (workflowName ? parseWorkflowName(workflowName)?.shortName : undefined) ??\n stepName ??\n workflowName ??\n (data.hookId as string) ??\n 'Details'\n );\n }, [selectedSpan?.data, selectedSpan?.resource]);\n\n const selectedResource = selectedSpan?.resource as string | undefined;\n const selectedResourceId = useMemo(() => {\n if (!selectedSpan?.data) return undefined;\n const data = selectedSpan.data as Record<string, unknown>;\n if (selectedSpan.resource === 'hook') {\n return (data.hookId as string | undefined) ?? selectedSpan.spanId;\n }\n\n return (\n (data.stepId as string) ??\n (data.runId as string) ??\n (data.hookId as string) ??\n selectedSpan.spanId\n );\n }, [selectedSpan?.data, selectedSpan?.resource, selectedSpan?.spanId]);\n\n return (\n <div\n data-pane=\"pane-root\"\n data-has-detail={activeSpan ? '' : undefined}\n className=\"grid w-full h-full max-h-full grid-cols-[minmax(100px,1fr)] data-[has-detail]:grid-cols-[minmax(100px,1fr)_clamp(280px,420px,100%)]\"\n >\n <div\n id=\"trace-parent\"\n className=\"grid grid-rows-[1fr] h-full min-h-0 overflow-hidden relative bg-background-100\"\n >\n <SplitPane\n startHeader={\n <div className=\"bg-background-100 border-b border-gray-alpha-400 h-10 min-h-10 flex items-center px-2 gap-1.5\">\n <Search className=\"w-3.5 h-3.5 shrink-0 text-gray-800\" />\n <input\n id=\"trace-viewer-search\"\n name=\"trace-viewer-search\"\n type=\"text\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n placeholder=\"Search spans...\"\n aria-label=\"Search spans\"\n className=\"flex-1 min-w-0 bg-transparent text-sm text-gray-1000 placeholder:text-gray-800 outline-none\"\n />\n {searchQuery && (\n <button\n type=\"button\"\n onClick={() => setSearchQuery('')}\n className=\"shrink-0 p-0.5 rounded-sm text-gray-800 hover:text-gray-1000 hover:bg-gray-200 transition-colors\"\n >\n <X className=\"w-3 h-3\" />\n </button>\n )}\n </div>\n }\n endHeader={\n <TimelineHeader markers={timeMarkers} hoverInfo={hoverInfo} />\n }\n >\n <div className=\"block overflow-visible\">\n <EventList\n spans={filteredSpans}\n activeSpanId={activeSpanId}\n onSelectSpan={handleSelectSpan}\n />\n </div>\n <div\n ref={timelineRef}\n className=\"block min-h-0 overflow-visible relative\"\n onDoubleClick={resetZoom}\n onMouseMove={handleTimelineMouseMove}\n onMouseLeave={handleTimelineMouseLeave}\n >\n <Timeline\n spans={filteredSpans}\n viewStart={viewport.start}\n viewEnd={viewport.end}\n markers={timeMarkers}\n selectedId={activeSpanId}\n onSelect={handleSelectSpan}\n hoverFraction={hoverFraction}\n altHeld={altHeld}\n />\n </div>\n </SplitPane>\n <div className=\"absolute right-3 bottom-3 z-[5] flex items-center border border-gray-alpha-400 rounded-lg bg-background-100 shadow-sm overflow-hidden divide-x divide-gray-alpha-400\">\n <button\n type=\"button\"\n className=\"flex items-center justify-center w-8 h-8 text-gray-900 cursor-pointer transition-colors duration-[120ms] ease-in-out hover:text-gray-1000 hover:bg-gray-alpha-100\"\n onClick={zoomOut}\n aria-label=\"Zoom out\"\n >\n <ZoomOut className=\"w-4 h-4\" />\n </button>\n <button\n type=\"button\"\n className=\"flex items-center justify-center w-8 h-8 text-gray-900 cursor-pointer transition-colors duration-[120ms] ease-in-out hover:text-gray-1000 hover:bg-gray-alpha-100\"\n onClick={resetZoom}\n aria-label=\"Reset zoom\"\n >\n <RotateCcw className=\"w-3.5 h-3.5\" />\n </button>\n <button\n type=\"button\"\n className=\"flex items-center justify-center w-8 h-8 text-gray-900 cursor-pointer transition-colors duration-[120ms] ease-in-out hover:text-gray-1000 hover:bg-gray-alpha-100\"\n onClick={zoomIn}\n aria-label=\"Zoom in\"\n >\n <ZoomIn className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n\n {/* Detail panel */}\n {activeSpan && sidebar ? (\n <aside className=\"flex flex-col h-full max-h-full bg-background-100 border-l border-gray-alpha-400 overflow-auto\">\n {/* Panel header */}\n <div className=\"flex-shrink-0 px-4 pt-4 pb-3\">\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"min-w-0 flex-1\">\n <span className=\"text-[15px] font-semibold text-gray-1000 truncate block\">\n {selectedSpanName}\n </span>\n {selectedResourceId && (\n <div className=\"mt-1 flex items-center gap-2\">\n {selectedResource && (\n <span\n className={`inline-flex items-center rounded-md px-1.5 py-0.5 text-[11px] font-medium leading-none shrink-0 ${\n selectedResource === 'step'\n ? 'bg-green-200 text-green-900'\n : selectedResource === 'run'\n ? 'bg-blue-200 text-blue-900'\n : selectedResource === 'hook'\n ? 'bg-yellow-200 text-yellow-900'\n : 'bg-gray-200 text-gray-900'\n }`}\n >\n {selectedResource.charAt(0).toUpperCase() +\n selectedResource.slice(1)}\n </span>\n )}\n <div\n className=\"flex items-center gap-1 text-[13px] font-mono text-gray-700 min-w-0\"\n title={selectedResourceId}\n >\n <span className=\"truncate\">{selectedResourceId}</span>\n <CopyButton\n copyText={selectedResourceId}\n ariaLabel=\"Copy ID\"\n className=\"shrink-0\"\n />\n </div>\n </div>\n )}\n </div>\n <button\n type=\"button\"\n className=\"p-1 rounded-md text-gray-900 hover:text-gray-1000 hover:bg-gray-alpha-200 transition-colors shrink-0\"\n onClick={clearActiveSpan}\n >\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n {/* Panel body */}\n <div className=\"flex-1 overflow-y-auto\">\n <ErrorBoundary>\n <EntityDetailPanel\n run={sidebar.run}\n onStreamClick={sidebar.onStreamClick}\n onRunClick={sidebar.onRunClick}\n spanDetailData={sidebar.spanDetailData}\n spanDetailError={sidebar.spanDetailError}\n spanDetailLoading={sidebar.spanDetailLoading}\n onSpanSelect={sidebar.onSpanSelect}\n onWakeUpSleep={sidebar.onWakeUpSleep}\n onLoadEventData={sidebar.onLoadEventData}\n onResolveHook={sidebar.onResolveHook}\n encryptionKey={sidebar.encryptionKey}\n onDecrypt={sidebar.onDecrypt}\n isDecrypting={sidebar.isDecrypting}\n selectedSpan={selectedSpan}\n />\n </ErrorBoundary>\n </div>\n </aside>\n ) : activeSpan ? (\n <DetailPanel\n span={activeSpan}\n rootStart={root.startTime}\n onClose={clearActiveSpan}\n />\n ) : null}\n </div>\n );\n}\n"]}
|
|
@@ -5,25 +5,20 @@ export interface RootBounds {
|
|
|
5
5
|
duration: number;
|
|
6
6
|
}
|
|
7
7
|
export declare function computeRootBounds(spans: Span[]): RootBounds;
|
|
8
|
-
export
|
|
9
|
-
toVisual(time: number): number;
|
|
10
|
-
fromVisual(fraction: number): number;
|
|
11
|
-
isCompressed: boolean;
|
|
12
|
-
}
|
|
13
|
-
export declare function buildTimeCompression(_spans: Span[], viewStart: number, viewEnd: number): TimeCompression;
|
|
8
|
+
export declare function getSpanDurationMs(span: Span): number;
|
|
14
9
|
export interface TimeMarker {
|
|
15
10
|
position: number;
|
|
16
11
|
label: string;
|
|
12
|
+
value: number;
|
|
17
13
|
}
|
|
18
14
|
export declare function computeTimeMarkers(viewDuration: number, offset: number): TimeMarker[];
|
|
19
|
-
export declare function computeCompressedTimeMarkers(compression: TimeCompression, viewStart: number, viewEnd: number, rootStart: number): TimeMarker[];
|
|
20
15
|
export interface SpanGap {
|
|
21
16
|
gapMs: number;
|
|
22
17
|
leftFrac: number;
|
|
23
18
|
rightFrac: number;
|
|
24
19
|
rowIndex: number;
|
|
25
20
|
}
|
|
26
|
-
export declare function computeSpanGaps(spans: Span[],
|
|
21
|
+
export declare function computeSpanGaps(spans: Span[], viewStart: number, viewEnd: number): SpanGap[];
|
|
27
22
|
export declare const RESOURCE_COLORS: Record<string, {
|
|
28
23
|
bar: string;
|
|
29
24
|
errorBar?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/components/new-trace-viewer/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAa,MAAM,uBAAuB,CAAC;AAO7D,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,UAAU,CAiB3D;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/components/new-trace-viewer/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAa,MAAM,uBAAuB,CAAC;AAO7D,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,UAAU,CAiB3D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAKpD;AAMD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAkBD,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,GACb,UAAU,EAAE,CAqBd;AAMD,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,IAAI,EAAE,EACb,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,OAAO,EAAE,CAkBX;AAMD,eAAO,MAAM,eAAe,EAAE,MAAM,CAClC,MAAM,EACN;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAOnC,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG;IAClD,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAEA;AAMD,MAAM,MAAM,aAAa,GACrB,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,UAAU,GACV,WAAW,GACX,SAAS,GACT,UAAU,GACV,UAAU,CAAC;AAEf,MAAM,WAAW,OAAO;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;CACvB;AA6PD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,EAAE,CAyBzD"}
|
|
@@ -16,19 +16,8 @@ export function computeRootBounds(spans) {
|
|
|
16
16
|
const duration = Math.max(maxEnd - minStart, 1);
|
|
17
17
|
return { startTime: minStart, endTime: maxEnd, duration };
|
|
18
18
|
}
|
|
19
|
-
export function
|
|
20
|
-
|
|
21
|
-
return {
|
|
22
|
-
isCompressed: false,
|
|
23
|
-
toVisual(time) {
|
|
24
|
-
if (range <= 0)
|
|
25
|
-
return 0;
|
|
26
|
-
return Math.min(Math.max((time - viewStart) / range, 0), 1);
|
|
27
|
-
},
|
|
28
|
-
fromVisual(fraction) {
|
|
29
|
-
return viewStart + fraction * range;
|
|
30
|
-
},
|
|
31
|
-
};
|
|
19
|
+
export function getSpanDurationMs(span) {
|
|
20
|
+
return Math.max(0, getHighResInMs(span.endTime) - getHighResInMs(span.startTime));
|
|
32
21
|
}
|
|
33
22
|
const NICE_INTERVALS = [
|
|
34
23
|
1, 2, 5, 10, 20, 50, 100, 200, 500, 1_000, 2_000, 5_000, 10_000, 20_000,
|
|
@@ -58,36 +47,17 @@ export function computeTimeMarkers(viewDuration, offset) {
|
|
|
58
47
|
markers.push({
|
|
59
48
|
position: Math.min(Math.max(position, 0), 1),
|
|
60
49
|
label: formatDuration(Math.abs(t), true),
|
|
50
|
+
value: t,
|
|
61
51
|
});
|
|
62
52
|
if (markers.length >= MAX_MARKERS)
|
|
63
53
|
break;
|
|
64
54
|
}
|
|
65
55
|
return markers;
|
|
66
56
|
}
|
|
67
|
-
export function
|
|
68
|
-
const
|
|
69
|
-
if (
|
|
57
|
+
export function computeSpanGaps(spans, viewStart, viewEnd) {
|
|
58
|
+
const range = viewEnd - viewStart;
|
|
59
|
+
if (range <= 0)
|
|
70
60
|
return [];
|
|
71
|
-
const maxTicks = 6;
|
|
72
|
-
const interval = pickInterval(viewDuration, maxTicks);
|
|
73
|
-
const offset = viewStart - rootStart;
|
|
74
|
-
const firstTick = Math.ceil(offset / interval) * interval;
|
|
75
|
-
const markers = [];
|
|
76
|
-
for (let t = firstTick; t <= offset + viewDuration; t += interval) {
|
|
77
|
-
const absTime = rootStart + t;
|
|
78
|
-
const position = compression.toVisual(absTime);
|
|
79
|
-
if (position < -0.01 || position > 1.01)
|
|
80
|
-
continue;
|
|
81
|
-
markers.push({
|
|
82
|
-
position: Math.min(Math.max(position, 0), 1),
|
|
83
|
-
label: formatDuration(Math.abs(t), true),
|
|
84
|
-
});
|
|
85
|
-
if (markers.length >= MAX_MARKERS)
|
|
86
|
-
break;
|
|
87
|
-
}
|
|
88
|
-
return markers;
|
|
89
|
-
}
|
|
90
|
-
export function computeSpanGaps(spans, compression) {
|
|
91
61
|
const gaps = [];
|
|
92
62
|
for (let i = 0; i < spans.length - 1; i++) {
|
|
93
63
|
const endTime = getHighResInMs(spans[i].endTime);
|
|
@@ -95,8 +65,8 @@ export function computeSpanGaps(spans, compression) {
|
|
|
95
65
|
const gapMs = startTime - endTime;
|
|
96
66
|
if (gapMs <= 0)
|
|
97
67
|
continue;
|
|
98
|
-
const leftFrac =
|
|
99
|
-
const rightFrac =
|
|
68
|
+
const leftFrac = Math.min(Math.max((endTime - viewStart) / range, 0), 1);
|
|
69
|
+
const rightFrac = Math.min(Math.max((startTime - viewStart) / range, 0), 1);
|
|
100
70
|
if (rightFrac - leftFrac < 0.001)
|
|
101
71
|
continue;
|
|
102
72
|
gaps.push({ gapMs, leftFrac, rightFrac, rowIndex: i });
|
|
@@ -249,32 +219,10 @@ function computeHookSegmentsFromSpan(startMs, duration, events) {
|
|
|
249
219
|
}
|
|
250
220
|
return segments;
|
|
251
221
|
}
|
|
252
|
-
function computeSleepSegmentsFromSpan(
|
|
253
|
-
const segments = [];
|
|
222
|
+
function computeSleepSegmentsFromSpan(_startMs, duration, _events) {
|
|
254
223
|
if (duration <= 0)
|
|
255
|
-
return
|
|
256
|
-
|
|
257
|
-
.filter((e) => e.name === 'wait_completed')
|
|
258
|
-
.map((e) => getHighResInMs(e.timestamp))
|
|
259
|
-
.sort((a, b) => a - b)[0];
|
|
260
|
-
if (completedTime === undefined) {
|
|
261
|
-
segments.push({ startFraction: 0, endFraction: 1, status: 'sleeping' });
|
|
262
|
-
return segments;
|
|
263
|
-
}
|
|
264
|
-
const completedFrac = timeToFraction(completedTime, startMs, duration);
|
|
265
|
-
if (completedFrac > 0.001) {
|
|
266
|
-
segments.push({
|
|
267
|
-
startFraction: 0,
|
|
268
|
-
endFraction: completedFrac,
|
|
269
|
-
status: 'sleeping',
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
|
-
segments.push({
|
|
273
|
-
startFraction: completedFrac,
|
|
274
|
-
endFraction: 1,
|
|
275
|
-
status: 'succeeded',
|
|
276
|
-
});
|
|
277
|
-
return segments;
|
|
224
|
+
return [];
|
|
225
|
+
return [{ startFraction: 0, endFraction: 1, status: 'sleeping' }];
|
|
278
226
|
}
|
|
279
227
|
function computeRunSegmentsFromSpan(startMs, duration, activeStartMs, events, attributes) {
|
|
280
228
|
const segments = [];
|
|
@@ -337,8 +285,7 @@ function computeV1RunSegments(startMs, duration, activeStartMs, runStatus) {
|
|
|
337
285
|
*/
|
|
338
286
|
export function computeSpanSegments(span) {
|
|
339
287
|
const startMs = getHighResInMs(span.startTime);
|
|
340
|
-
const
|
|
341
|
-
const duration = endMs - startMs;
|
|
288
|
+
const duration = getSpanDurationMs(span);
|
|
342
289
|
const activeStartMs = span.activeStartTime
|
|
343
290
|
? getHighResInMs(span.activeStartTime)
|
|
344
291
|
: undefined;
|