@workflow/web-shared 5.0.0-beta.41 → 5.0.0-beta.43
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/event-list-view.d.ts +10 -2
- package/dist/components/event-list-view.d.ts.map +1 -1
- package/dist/components/event-list-view.js +52 -26
- package/dist/components/sidebar/attributes-block.d.ts.map +1 -1
- package/dist/components/sidebar/attributes-block.js +3 -6
- package/dist/components/sidebar/conversation-view.d.ts.map +1 -1
- package/dist/components/sidebar/conversation-view.js +19 -36
- package/dist/components/sidebar/entity-detail-panel.d.ts +5 -0
- package/dist/components/sidebar/entity-detail-panel.d.ts.map +1 -1
- package/dist/components/sidebar/entity-detail-panel.js +2 -2
- package/dist/components/sidebar/events-list.d.ts +7 -1
- package/dist/components/sidebar/events-list.d.ts.map +1 -1
- package/dist/components/sidebar/events-list.js +6 -5
- package/dist/components/sidebar/resolve-hook-modal.d.ts.map +1 -1
- package/dist/components/sidebar/resolve-hook-modal.js +4 -145
- package/dist/components/sidebar/sidebar-data-context.d.ts +6 -0
- package/dist/components/sidebar/sidebar-data-context.d.ts.map +1 -1
- package/dist/components/sidebar/sidebar-data-context.js +1 -1
- package/dist/components/stream-viewer-skeleton.js +6 -6
- package/dist/components/stream-viewer.js +2 -2
- package/dist/components/trace-viewer/components/detail-panel.d.ts.map +1 -1
- package/dist/components/trace-viewer/components/detail-panel.js +2 -1
- package/dist/components/trace-viewer/components/middle-truncate/measurement-batch.d.ts +9 -0
- package/dist/components/trace-viewer/components/middle-truncate/measurement-batch.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/middle-truncate/measurement-batch.js +29 -0
- package/dist/components/trace-viewer/components/middle-truncate/middle-truncate.d.ts.map +1 -1
- package/dist/components/trace-viewer/components/middle-truncate/middle-truncate.js +16 -8
- package/dist/components/trace-viewer/components/middle-truncate/use-middle-truncate.d.ts.map +1 -1
- package/dist/components/trace-viewer/components/middle-truncate/use-middle-truncate.js +83 -19
- package/dist/components/trace-viewer/components/timeline.d.ts.map +1 -1
- package/dist/components/trace-viewer/components/timeline.js +13 -22
- package/dist/components/trace-viewer/components/trace-viewer-skeleton.d.ts.map +1 -1
- package/dist/components/trace-viewer/components/trace-viewer-skeleton.js +58 -18
- package/dist/components/trace-viewer/icons.js +5 -5
- package/dist/components/trace-viewer/utils.d.ts +6 -10
- package/dist/components/trace-viewer/utils.d.ts.map +1 -1
- package/dist/components/trace-viewer/utils.js +14 -24
- package/dist/components/trace-viewer.d.ts.map +1 -1
- package/dist/components/trace-viewer.js +12 -4
- package/dist/components/ui/context-card.d.ts.map +1 -1
- package/dist/components/ui/context-card.js +9 -21
- package/dist/components/ui/data-inspector.d.ts.map +1 -1
- package/dist/components/ui/data-inspector.js +8 -35
- package/dist/components/ui/duplicate-event-tooltip.d.ts +15 -0
- package/dist/components/ui/duplicate-event-tooltip.d.ts.map +1 -0
- package/dist/components/ui/duplicate-event-tooltip.js +19 -0
- package/dist/components/ui/menu-dropdown.d.ts.map +1 -1
- package/dist/components/ui/menu-dropdown.js +3 -19
- package/dist/components/ui/skeleton.js +2 -2
- package/dist/components/ui/spinner.d.ts.map +1 -1
- package/dist/components/ui/spinner.js +5 -11
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/lib/duplicate-events.d.ts +27 -0
- package/dist/lib/duplicate-events.d.ts.map +1 -0
- package/dist/lib/duplicate-events.js +166 -0
- package/dist/lib/event-materialization.d.ts +15 -2
- package/dist/lib/event-materialization.d.ts.map +1 -1
- package/dist/lib/event-materialization.js +19 -4
- package/dist/lib/trace-builder.d.ts +16 -1
- package/dist/lib/trace-builder.d.ts.map +1 -1
- package/dist/lib/trace-builder.js +23 -4
- package/package.json +4 -4
- package/src/components/event-list-view.tsx +70 -32
- package/src/components/sidebar/attributes-block.tsx +4 -11
- package/src/components/sidebar/conversation-view.tsx +25 -79
- package/src/components/sidebar/entity-detail-panel.tsx +6 -0
- package/src/components/sidebar/events-list.tsx +21 -3
- package/src/components/sidebar/resolve-hook-modal.tsx +23 -186
- package/src/components/sidebar/sidebar-data-context.tsx +6 -0
- package/src/components/stream-viewer-skeleton.tsx +5 -5
- package/src/components/stream-viewer.tsx +1 -1
- package/src/components/trace-viewer/components/detail-panel.tsx +1 -0
- package/src/components/trace-viewer/components/middle-truncate/measurement-batch.ts +47 -0
- package/src/components/trace-viewer/components/middle-truncate/middle-truncate.tsx +15 -7
- package/src/components/trace-viewer/components/middle-truncate/use-middle-truncate.ts +132 -38
- package/src/components/trace-viewer/components/timeline.tsx +21 -39
- package/src/components/trace-viewer/components/trace-viewer-skeleton.tsx +63 -35
- package/src/components/trace-viewer/icons.tsx +4 -4
- package/src/components/trace-viewer/utils.test.ts +5 -7
- package/src/components/trace-viewer/utils.ts +17 -31
- package/src/components/trace-viewer.tsx +15 -3
- package/src/components/ui/context-card.tsx +16 -26
- package/src/components/ui/data-inspector.tsx +20 -65
- package/src/components/ui/duplicate-event-tooltip.tsx +44 -0
- package/src/components/ui/menu-dropdown.tsx +8 -22
- package/src/components/ui/skeleton.tsx +2 -2
- package/src/components/ui/spinner.tsx +4 -8
- package/src/index.ts +4 -0
- package/src/lib/duplicate-events.test.ts +339 -0
- package/src/lib/duplicate-events.ts +188 -0
- package/src/lib/event-materialization.test.ts +117 -0
- package/src/lib/event-materialization.ts +23 -3
- package/src/lib/trace-builder.test.ts +74 -0
- package/src/lib/trace-builder.ts +30 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { ArrowLeft, ArrowRight } from 'lucide-react';
|
|
4
|
-
import type {
|
|
4
|
+
import type { ReactNode } from 'react';
|
|
5
5
|
import {
|
|
6
6
|
Fragment,
|
|
7
7
|
memo,
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
computeSpanGaps,
|
|
29
29
|
computeSpanMarkers,
|
|
30
30
|
computeSpanSegments,
|
|
31
|
-
|
|
31
|
+
getResourceClassNames,
|
|
32
32
|
getSpanDurationMs,
|
|
33
33
|
isSpanErrored,
|
|
34
34
|
} from '../utils';
|
|
@@ -62,11 +62,6 @@ const SEGMENT_CLASSES: Record<SegmentStatus, string> = {
|
|
|
62
62
|
received: 'bg-blue-200 border border-blue-500',
|
|
63
63
|
};
|
|
64
64
|
|
|
65
|
-
const TIMELINE_INSET_STYLE: CSSProperties = {
|
|
66
|
-
left: TIMELINE_PADDING_PX,
|
|
67
|
-
right: TIMELINE_PADDING_PX,
|
|
68
|
-
};
|
|
69
|
-
|
|
70
65
|
const STRIPED_SEGMENT_STATUSES: ReadonlySet<SegmentStatus> = new Set([
|
|
71
66
|
'pending',
|
|
72
67
|
'running',
|
|
@@ -260,18 +255,18 @@ function BoundaryArrow({
|
|
|
260
255
|
}
|
|
261
256
|
|
|
262
257
|
function PlainBar({
|
|
263
|
-
|
|
264
|
-
border,
|
|
258
|
+
className,
|
|
265
259
|
label,
|
|
266
260
|
}: {
|
|
267
|
-
|
|
268
|
-
border: string;
|
|
261
|
+
className: string;
|
|
269
262
|
label: string | null;
|
|
270
263
|
}): ReactNode {
|
|
271
264
|
return (
|
|
272
265
|
<div
|
|
273
|
-
className=
|
|
274
|
-
|
|
266
|
+
className={cn(
|
|
267
|
+
'relative h-6 w-full min-w-1 rounded-[0.25rem] border',
|
|
268
|
+
className
|
|
269
|
+
)}
|
|
275
270
|
>
|
|
276
271
|
{label ? <DurationLabel label={label} /> : null}
|
|
277
272
|
</div>
|
|
@@ -352,14 +347,13 @@ function SegmentBar({
|
|
|
352
347
|
<div
|
|
353
348
|
key={i}
|
|
354
349
|
className={cn(
|
|
355
|
-
'absolute h-full overflow-hidden rounded-[0.25rem]',
|
|
350
|
+
'absolute h-full min-w-px overflow-hidden rounded-[0.25rem]',
|
|
356
351
|
SEGMENT_CLASSES[seg.status]
|
|
357
352
|
)}
|
|
358
353
|
style={{
|
|
359
354
|
// 1px gap between adjacent segments, distributed equally.
|
|
360
355
|
left: `calc(${seg.leftPct}% + 0.5px)`,
|
|
361
356
|
width: `calc(${seg.widthPct}% - 1px)`,
|
|
362
|
-
minWidth: 1,
|
|
363
357
|
}}
|
|
364
358
|
>
|
|
365
359
|
{STRIPED_SEGMENT_STATUSES.has(seg.status) ? (
|
|
@@ -457,13 +451,10 @@ const TimelineBar = memo(function TimelineBar({
|
|
|
457
451
|
markers.length > 0 || offscreen.left !== null || offscreen.right !== null;
|
|
458
452
|
|
|
459
453
|
const isErrored = isSpanErrored(span);
|
|
460
|
-
const colors =
|
|
461
|
-
const
|
|
462
|
-
? (colors.
|
|
463
|
-
: colors.
|
|
464
|
-
const fallbackBorder = isErrored
|
|
465
|
-
? (colors.errorBorder ?? 'var(--ds-red-500)')
|
|
466
|
-
: colors.border;
|
|
454
|
+
const colors = getResourceClassNames(span.resource);
|
|
455
|
+
const fallbackClassName = isErrored
|
|
456
|
+
? (colors.errorClassName ?? 'border-red-500 bg-red-200')
|
|
457
|
+
: colors.className;
|
|
467
458
|
|
|
468
459
|
const totalLabel = formatDurationPrecise(totalDurationMs);
|
|
469
460
|
const showTotalLabel =
|
|
@@ -486,7 +477,7 @@ const TimelineBar = memo(function TimelineBar({
|
|
|
486
477
|
)}
|
|
487
478
|
onClick={handleClick}
|
|
488
479
|
>
|
|
489
|
-
<div className="absolute inset-y-0"
|
|
480
|
+
<div className="absolute inset-x-4 inset-y-0">
|
|
490
481
|
<div
|
|
491
482
|
className="absolute top-1/2 h-6 -translate-y-1/2 overflow-hidden rounded-[0.25rem]"
|
|
492
483
|
style={getBarPositionStyle(geometry)}
|
|
@@ -495,15 +486,13 @@ const TimelineBar = memo(function TimelineBar({
|
|
|
495
486
|
<BoundaryArrow direction={geometry.mode.direction} />
|
|
496
487
|
) : geometry.mode.kind === 'tiny' ? (
|
|
497
488
|
<div
|
|
498
|
-
className=
|
|
499
|
-
style={{ background: fallbackBg, borderColor: fallbackBorder }}
|
|
489
|
+
className={cn('h-6 rounded-[0.25rem] border', fallbackClassName)}
|
|
500
490
|
/>
|
|
501
491
|
) : segments.length > 0 ? (
|
|
502
492
|
<SegmentBar segments={segments} showLabels={!hasMarkers} />
|
|
503
493
|
) : (
|
|
504
494
|
<PlainBar
|
|
505
|
-
|
|
506
|
-
border={fallbackBorder}
|
|
495
|
+
className={fallbackClassName}
|
|
507
496
|
label={showTotalLabel ? totalLabel : null}
|
|
508
497
|
/>
|
|
509
498
|
)}
|
|
@@ -612,10 +601,9 @@ const DeltaMeasureLine = memo(function DeltaMeasureLine({
|
|
|
612
601
|
return (
|
|
613
602
|
<>
|
|
614
603
|
<div
|
|
615
|
-
className="absolute h-px bg-amber-800"
|
|
604
|
+
className="absolute h-px w-1 bg-amber-800"
|
|
616
605
|
style={{
|
|
617
606
|
left: Math.min(anchorX, guideX),
|
|
618
|
-
width: MEASURE_GUIDE_OUTSET_PX,
|
|
619
607
|
top: anchorCenterY,
|
|
620
608
|
}}
|
|
621
609
|
/>
|
|
@@ -781,8 +769,7 @@ export function Timeline({
|
|
|
781
769
|
>
|
|
782
770
|
<div
|
|
783
771
|
aria-hidden
|
|
784
|
-
className="absolute inset-
|
|
785
|
-
style={TIMELINE_INSET_STYLE}
|
|
772
|
+
className="pointer-events-none absolute inset-x-4 inset-y-0"
|
|
786
773
|
>
|
|
787
774
|
{markers.map((marker) =>
|
|
788
775
|
// Skip the "0s" origin marker since the left edge already implies it.
|
|
@@ -796,10 +783,7 @@ export function Timeline({
|
|
|
796
783
|
)}
|
|
797
784
|
</div>
|
|
798
785
|
{hover != null && (
|
|
799
|
-
<div
|
|
800
|
-
className="absolute inset-y-0 pointer-events-none z-10"
|
|
801
|
-
style={TIMELINE_INSET_STYLE}
|
|
802
|
-
>
|
|
786
|
+
<div className="pointer-events-none absolute inset-x-4 inset-y-0 z-10">
|
|
803
787
|
<div
|
|
804
788
|
className="absolute top-0 bottom-0 w-px bg-gray-alpha-500"
|
|
805
789
|
style={{ left: `${hover.fraction * 100}%` }}
|
|
@@ -824,8 +808,7 @@ export function Timeline({
|
|
|
824
808
|
{altHeld && anchorIndex < 0 && (
|
|
825
809
|
<div
|
|
826
810
|
aria-hidden
|
|
827
|
-
className="absolute inset-
|
|
828
|
-
style={TIMELINE_INSET_STYLE}
|
|
811
|
+
className="pointer-events-none absolute inset-x-4 inset-y-0"
|
|
829
812
|
>
|
|
830
813
|
{gapMeasurements.map((gap) => (
|
|
831
814
|
<DeltaMeasureLine
|
|
@@ -839,8 +822,7 @@ export function Timeline({
|
|
|
839
822
|
{measurement && (
|
|
840
823
|
<div
|
|
841
824
|
aria-hidden
|
|
842
|
-
className="absolute inset-
|
|
843
|
-
style={TIMELINE_INSET_STYLE}
|
|
825
|
+
className="pointer-events-none absolute inset-x-4 inset-y-0 z-20"
|
|
844
826
|
>
|
|
845
827
|
<DeltaMeasureLine {...measurement} timelineWidth={timelineWidth} />
|
|
846
828
|
</div>
|
|
@@ -1,19 +1,62 @@
|
|
|
1
1
|
import { Skeleton } from '../../ui/skeleton';
|
|
2
|
-
import { DEFAULT_START_PX, paneColTemplate } from './pane-constants';
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
{
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
3
|
+
const ROWS = [
|
|
4
|
+
{
|
|
5
|
+
id: 'r0',
|
|
6
|
+
nameClassName: 'w-[62%]',
|
|
7
|
+
offsetClassName: 'left-0',
|
|
8
|
+
barClassName: 'w-[72%]',
|
|
9
|
+
topClassName: 'top-0',
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
id: 'r1',
|
|
13
|
+
nameClassName: 'w-[78%]',
|
|
14
|
+
offsetClassName: 'left-[6%]',
|
|
15
|
+
barClassName: 'w-[48%]',
|
|
16
|
+
topClassName: 'top-[3.5px]',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: 'r2',
|
|
20
|
+
nameClassName: 'w-1/2',
|
|
21
|
+
offsetClassName: 'left-[10%]',
|
|
22
|
+
barClassName: 'w-[55%]',
|
|
23
|
+
topClassName: 'top-[7px]',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: 'r3',
|
|
27
|
+
nameClassName: 'w-[84%]',
|
|
28
|
+
offsetClassName: 'left-[18%]',
|
|
29
|
+
barClassName: 'w-[30%]',
|
|
30
|
+
topClassName: 'top-[10.5px]',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: 'r4',
|
|
34
|
+
nameClassName: 'w-[45%]',
|
|
35
|
+
offsetClassName: 'left-[18%]',
|
|
36
|
+
barClassName: 'w-[42%]',
|
|
37
|
+
topClassName: 'top-[14px]',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
id: 'r5',
|
|
41
|
+
nameClassName: 'w-[66%]',
|
|
42
|
+
offsetClassName: 'left-[34%]',
|
|
43
|
+
barClassName: 'w-[38%]',
|
|
44
|
+
topClassName: 'top-[17.5px]',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: 'r6',
|
|
48
|
+
nameClassName: 'w-[55%]',
|
|
49
|
+
offsetClassName: 'left-[41%]',
|
|
50
|
+
barClassName: 'w-1/4',
|
|
51
|
+
topClassName: 'top-[21px]',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: 'r7',
|
|
55
|
+
nameClassName: 'w-2/5',
|
|
56
|
+
offsetClassName: 'left-1/2',
|
|
57
|
+
barClassName: 'w-[30%]',
|
|
58
|
+
topClassName: 'top-[24.5px]',
|
|
59
|
+
},
|
|
17
60
|
];
|
|
18
61
|
|
|
19
62
|
const HEADER_MARKERS = ['m0', 'm1', 'm2', 'm3'];
|
|
@@ -36,25 +79,17 @@ export function TraceViewerSkeleton() {
|
|
|
36
79
|
{/* Minimap strip: thin density lines tracing the same shape as the bars */}
|
|
37
80
|
<div className="relative h-10 min-h-10 shrink-0 border-b border-gray-alpha-400">
|
|
38
81
|
<div className="absolute inset-x-4 top-[6px]">
|
|
39
|
-
{ROWS.map((row
|
|
82
|
+
{ROWS.map((row) => (
|
|
40
83
|
<Skeleton
|
|
41
84
|
key={row.id}
|
|
42
|
-
className=
|
|
43
|
-
style={{
|
|
44
|
-
left: `${row.off}%`,
|
|
45
|
-
width: `${row.bar}%`,
|
|
46
|
-
top: index * 3.5,
|
|
47
|
-
}}
|
|
85
|
+
className={`absolute h-[3px] rounded-full ${row.offsetClassName} ${row.barClassName} ${row.topClassName}`}
|
|
48
86
|
/>
|
|
49
87
|
))}
|
|
50
88
|
</div>
|
|
51
89
|
</div>
|
|
52
90
|
|
|
53
91
|
{/* Header row: search header | divider | timeline header */}
|
|
54
|
-
<div
|
|
55
|
-
className="shrink-0 grid"
|
|
56
|
-
style={{ gridTemplateColumns: COL_TEMPLATE }}
|
|
57
|
-
>
|
|
92
|
+
<div className="grid shrink-0 grid-cols-[340px_1px_minmax(50px,1fr)]">
|
|
58
93
|
<div className="h-10 min-h-10 flex items-center border-b border-gray-alpha-400 pl-4 pr-2 gap-1.5">
|
|
59
94
|
<Skeleton className="w-3.5 h-3.5 shrink-0 rounded-sm" />
|
|
60
95
|
<Skeleton className="h-3.5 w-40" />
|
|
@@ -70,10 +105,7 @@ export function TraceViewerSkeleton() {
|
|
|
70
105
|
</div>
|
|
71
106
|
|
|
72
107
|
{/* Content row: event list | gutter | timeline */}
|
|
73
|
-
<div
|
|
74
|
-
className="grid flex-1 min-h-0 overflow-hidden"
|
|
75
|
-
style={{ gridTemplateColumns: COL_TEMPLATE }}
|
|
76
|
-
>
|
|
108
|
+
<div className="grid min-h-0 flex-1 grid-cols-[340px_1px_minmax(50px,1fr)] overflow-hidden">
|
|
77
109
|
{/* Sidebar event rows */}
|
|
78
110
|
<div className="block overflow-visible">
|
|
79
111
|
<ul className="block divide-y divide-gray-alpha-400 border-b border-gray-alpha-400">
|
|
@@ -81,10 +113,7 @@ export function TraceViewerSkeleton() {
|
|
|
81
113
|
<li key={row.id} className="h-10 flex items-center pl-4 pr-2">
|
|
82
114
|
<div className="flex min-w-0 flex-1 items-center gap-2">
|
|
83
115
|
<Skeleton className="w-4 h-4 shrink-0 rounded-sm" />
|
|
84
|
-
<Skeleton
|
|
85
|
-
className="h-3.5"
|
|
86
|
-
style={{ width: `${row.name}%` }}
|
|
87
|
-
/>
|
|
116
|
+
<Skeleton className={`h-3.5 ${row.nameClassName}`} />
|
|
88
117
|
</div>
|
|
89
118
|
<Skeleton className="ml-2 h-3.5 w-10 shrink-0" />
|
|
90
119
|
</li>
|
|
@@ -101,8 +130,7 @@ export function TraceViewerSkeleton() {
|
|
|
101
130
|
<div key={row.id} className="relative h-10">
|
|
102
131
|
<div className="absolute inset-x-4 inset-y-0">
|
|
103
132
|
<Skeleton
|
|
104
|
-
className=
|
|
105
|
-
style={{ left: `${row.off}%`, width: `${row.bar}%` }}
|
|
133
|
+
className={`absolute top-1/2 h-6 -translate-y-1/2 rounded-[0.25rem] ${row.offsetClassName} ${row.barClassName}`}
|
|
106
134
|
/>
|
|
107
135
|
</div>
|
|
108
136
|
</div>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
const WorkflowIcon = () => {
|
|
2
2
|
return (
|
|
3
3
|
<svg
|
|
4
|
+
aria-hidden="true"
|
|
4
5
|
data-testid="geist-icon"
|
|
5
6
|
height="16"
|
|
6
7
|
strokeLinejoin="round"
|
|
7
|
-
style={{ color: 'currentColor' }}
|
|
8
8
|
viewBox="0 0 16 16"
|
|
9
9
|
width="16"
|
|
10
10
|
>
|
|
@@ -19,12 +19,12 @@ const WorkflowIcon = () => {
|
|
|
19
19
|
const WebhookIcon = () => {
|
|
20
20
|
return (
|
|
21
21
|
<svg
|
|
22
|
+
aria-hidden="true"
|
|
22
23
|
data-testid="geist-icon"
|
|
23
24
|
height="16"
|
|
24
25
|
strokeLinejoin="round"
|
|
25
26
|
viewBox="0 0 16 16"
|
|
26
27
|
width="16"
|
|
27
|
-
style={{ color: 'currentColor' }}
|
|
28
28
|
>
|
|
29
29
|
<path
|
|
30
30
|
fillRule="evenodd"
|
|
@@ -39,12 +39,12 @@ const WebhookIcon = () => {
|
|
|
39
39
|
const SleepIcon = () => {
|
|
40
40
|
return (
|
|
41
41
|
<svg
|
|
42
|
+
aria-hidden="true"
|
|
42
43
|
data-testid="geist-icon"
|
|
43
44
|
height="16"
|
|
44
45
|
strokeLinejoin="round"
|
|
45
46
|
viewBox="0 0 16 16"
|
|
46
47
|
width="16"
|
|
47
|
-
style={{ color: 'currentColor' }}
|
|
48
48
|
>
|
|
49
49
|
<path
|
|
50
50
|
fillRule="evenodd"
|
|
@@ -59,12 +59,12 @@ const SleepIcon = () => {
|
|
|
59
59
|
const StepForwardIcon = () => {
|
|
60
60
|
return (
|
|
61
61
|
<svg
|
|
62
|
+
aria-hidden="true"
|
|
62
63
|
data-testid="geist-icon"
|
|
63
64
|
height="16"
|
|
64
65
|
strokeLinejoin="round"
|
|
65
66
|
viewBox="0 0 16 16"
|
|
66
67
|
width="16"
|
|
67
|
-
style={{ color: 'currentColor' }}
|
|
68
68
|
>
|
|
69
69
|
<path
|
|
70
70
|
fillRule="evenodd"
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
computeSpanMarkers,
|
|
8
8
|
computeSpanSegments,
|
|
9
9
|
computeTimeMarkers,
|
|
10
|
-
|
|
10
|
+
getResourceClassNames,
|
|
11
11
|
} from './utils';
|
|
12
12
|
|
|
13
13
|
/** Build a high-res timestamp tuple ([seconds, nanoseconds]) for a given ms. */
|
|
@@ -248,13 +248,11 @@ describe('computeTimeMarkers', () => {
|
|
|
248
248
|
});
|
|
249
249
|
});
|
|
250
250
|
|
|
251
|
-
describe('
|
|
251
|
+
describe('getResourceClassNames', () => {
|
|
252
252
|
it('uses gray for hooks (passive spans), not amber', () => {
|
|
253
|
-
expect(
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
errorBg: 'var(--ds-red-200)',
|
|
257
|
-
errorBorder: 'var(--ds-red-500)',
|
|
253
|
+
expect(getResourceClassNames('hook')).toEqual({
|
|
254
|
+
className: 'border-gray-500 bg-gray-200',
|
|
255
|
+
errorClassName: 'border-red-500 bg-red-200',
|
|
258
256
|
});
|
|
259
257
|
});
|
|
260
258
|
});
|
|
@@ -279,55 +279,41 @@ export function computeSpanDelta(
|
|
|
279
279
|
// Resource colors
|
|
280
280
|
// ---------------------------------------------------------------------------
|
|
281
281
|
|
|
282
|
-
export const
|
|
282
|
+
export const RESOURCE_CLASS_NAMES: Record<
|
|
283
283
|
string,
|
|
284
284
|
{
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
errorBg?: string;
|
|
288
|
-
errorBorder?: string;
|
|
285
|
+
className: string;
|
|
286
|
+
errorClassName?: string;
|
|
289
287
|
}
|
|
290
288
|
> = {
|
|
291
289
|
run: {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
errorBg: 'var(--ds-red-200)',
|
|
295
|
-
errorBorder: 'var(--ds-red-500)',
|
|
290
|
+
className: 'border-blue-500 bg-blue-200',
|
|
291
|
+
errorClassName: 'border-red-500 bg-red-200',
|
|
296
292
|
},
|
|
297
293
|
step: {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
errorBg: 'var(--ds-red-200)',
|
|
301
|
-
errorBorder: 'var(--ds-red-500)',
|
|
294
|
+
className: 'border-green-500 bg-green-200',
|
|
295
|
+
errorClassName: 'border-red-500 bg-red-200',
|
|
302
296
|
},
|
|
303
297
|
// Passive spans (hooks) stay gray — matches event-list icons and the minimap.
|
|
304
298
|
hook: {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
errorBg: 'var(--ds-red-200)',
|
|
308
|
-
errorBorder: 'var(--ds-red-500)',
|
|
299
|
+
className: 'border-gray-500 bg-gray-200',
|
|
300
|
+
errorClassName: 'border-red-500 bg-red-200',
|
|
309
301
|
},
|
|
310
302
|
sleep: {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
errorBg: 'var(--ds-red-200)',
|
|
314
|
-
errorBorder: 'var(--ds-red-500)',
|
|
303
|
+
className: 'border-purple-500 bg-purple-200',
|
|
304
|
+
errorClassName: 'border-red-500 bg-red-200',
|
|
315
305
|
},
|
|
316
306
|
default: {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
errorBg: 'var(--ds-red-200)',
|
|
320
|
-
errorBorder: 'var(--ds-red-500)',
|
|
307
|
+
className: 'border-gray-500 bg-gray-200',
|
|
308
|
+
errorClassName: 'border-red-500 bg-red-200',
|
|
321
309
|
},
|
|
322
310
|
};
|
|
323
311
|
|
|
324
|
-
export function
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
errorBg?: string;
|
|
328
|
-
errorBorder?: string;
|
|
312
|
+
export function getResourceClassNames(resource: string): {
|
|
313
|
+
className: string;
|
|
314
|
+
errorClassName?: string;
|
|
329
315
|
} {
|
|
330
|
-
return
|
|
316
|
+
return RESOURCE_CLASS_NAMES[resource] ?? RESOURCE_CLASS_NAMES.default;
|
|
331
317
|
}
|
|
332
318
|
|
|
333
319
|
// ---------------------------------------------------------------------------
|
|
@@ -30,16 +30,28 @@ const TraceViewer = ({
|
|
|
30
30
|
if (!run?.runId) {
|
|
31
31
|
return undefined;
|
|
32
32
|
}
|
|
33
|
-
|
|
33
|
+
// `hasMore` is the only place that knows whether more of the log is still
|
|
34
|
+
// to be fetched, and a repeat can only be told apart from the event it
|
|
35
|
+
// repeats with the whole log in hand.
|
|
36
|
+
return buildTrace(run, events, new Date(), {
|
|
37
|
+
isCompleteHistory: !hasMore,
|
|
38
|
+
});
|
|
34
39
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- `new Date()` is intentionally not a dep
|
|
35
|
-
}, [run, events]);
|
|
40
|
+
}, [run, events, hasMore]);
|
|
41
|
+
|
|
42
|
+
// The sidebar shows one entity's slice of the log, so it takes the trace's
|
|
43
|
+
// answer rather than recomputing one from the slice.
|
|
44
|
+
const sidebarValue = useMemo(
|
|
45
|
+
() => ({ ...sidebarData, duplicateEventIds: trace?.duplicateEventIds }),
|
|
46
|
+
[sidebarData, trace]
|
|
47
|
+
);
|
|
36
48
|
|
|
37
49
|
if (!trace || (loading && events.length === 0)) {
|
|
38
50
|
return <TraceViewerSkeleton />;
|
|
39
51
|
}
|
|
40
52
|
|
|
41
53
|
return (
|
|
42
|
-
<SidebarDataProvider value={
|
|
54
|
+
<SidebarDataProvider value={sidebarValue}>
|
|
43
55
|
<div className="relative w-full h-full flex">
|
|
44
56
|
<TraceViewerComponent
|
|
45
57
|
trace={trace}
|
|
@@ -267,17 +267,17 @@ export function ContextCardProvider({
|
|
|
267
267
|
ref={ref}
|
|
268
268
|
>
|
|
269
269
|
<div
|
|
270
|
-
className=
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
}
|
|
270
|
+
className={cn(
|
|
271
|
+
'min-w-max transition-all duration-150 ease-[easing-function:cubic-bezier(0.3,_0.57,_0.07,_0.95)] will-change-[transform,width,height] motion-reduce:!transition-none',
|
|
272
|
+
visible ? 'opacity-100' : 'opacity-0'
|
|
273
|
+
)}
|
|
274
274
|
>
|
|
275
275
|
<div
|
|
276
276
|
className={cn(
|
|
277
277
|
'absolute bg-background-100 bg-clip-padding rounded-[6px] overflow-visible pointer-events-none z-[1000000] shadow-[var(--ds-shadow-tooltip),0_0_0_1px_var(--ds-background-100)] w-fit [--context-card-tip-stroke:#DBDBDB] dark-theme:[--context-card-tip-stroke:#252525]',
|
|
278
278
|
skipTransition
|
|
279
279
|
? '!transition-none'
|
|
280
|
-
: 'transition-[transform,width,height] duration-
|
|
280
|
+
: 'transition-[transform,width,height] duration-[250ms] ease-[easing-function:cubic-bezier(0.29,0.31,0.05,0.96)] will-change-[transform,width,height] motion-reduce:!transition-none'
|
|
281
281
|
)}
|
|
282
282
|
data-skip-transition={skipTransition}
|
|
283
283
|
style={{
|
|
@@ -301,7 +301,7 @@ export function ContextCardProvider({
|
|
|
301
301
|
},
|
|
302
302
|
skipTransition
|
|
303
303
|
? '!transition-none'
|
|
304
|
-
: 'transition-[transform,width,height] duration-
|
|
304
|
+
: 'transition-[transform,width,height] duration-[250ms] ease-[easing-function:cubic-bezier(0.29,0.31,0.05,0.96)] will-change-[transform,width,height] motion-reduce:!transition-none'
|
|
305
305
|
)}
|
|
306
306
|
style={{
|
|
307
307
|
...(activeBounds.side === 'top' ||
|
|
@@ -328,12 +328,7 @@ export function ContextCardProvider({
|
|
|
328
328
|
<path
|
|
329
329
|
d="M15 -0.5V0.5H12.9834L12.8184 0.508789C12.4377 0.550822 12.0853 0.738056 11.8359 1.03418L8.53027 4.95996C7.73114 5.90893 6.26886 5.90892 5.46973 4.95996L2.16406 1.03418C1.87905 0.695733 1.45907 0.5 1.0166 0.5H-1V-0.5H15Z"
|
|
330
330
|
fill="var(--ds-background-100)"
|
|
331
|
-
|
|
332
|
-
fill: 'var(--ds-background-100)',
|
|
333
|
-
fillOpacity: 1,
|
|
334
|
-
stroke: 'var(--context-card-tip-stroke)',
|
|
335
|
-
strokeOpacity: 1,
|
|
336
|
-
}}
|
|
331
|
+
className="fill-background-100 stroke-[var(--context-card-tip-stroke)]"
|
|
337
332
|
/>
|
|
338
333
|
</g>
|
|
339
334
|
<defs>
|
|
@@ -342,7 +337,7 @@ export function ContextCardProvider({
|
|
|
342
337
|
width="14"
|
|
343
338
|
height="7"
|
|
344
339
|
fill="white"
|
|
345
|
-
|
|
340
|
+
className="fill-background-100"
|
|
346
341
|
/>
|
|
347
342
|
</clipPath>
|
|
348
343
|
</defs>
|
|
@@ -748,30 +743,25 @@ export function ContextCardTrigger({
|
|
|
748
743
|
? createPortal(
|
|
749
744
|
<div
|
|
750
745
|
className={cn(
|
|
751
|
-
'absolute top-0 p-3 left-0 max-w-max transition-[transform,width,height] duration-
|
|
752
|
-
skipTransition && '!transition-none'
|
|
746
|
+
'absolute top-0 p-3 left-0 max-w-max transition-[transform,width,height] duration-[250ms] ease-[easing-function:cubic-bezier(0.29,0.31,0.05,0.96)] will-change-[transform,width,height] motion-reduce:!transition-none',
|
|
747
|
+
skipTransition && '!transition-none',
|
|
748
|
+
noPadding && 'p-0',
|
|
749
|
+
rootVisible && visible && !ignoreCardPointerEvents
|
|
750
|
+
? 'pointer-events-auto'
|
|
751
|
+
: 'pointer-events-none'
|
|
753
752
|
)}
|
|
754
753
|
key={id}
|
|
755
754
|
ref={contentRef}
|
|
756
|
-
style={{
|
|
757
|
-
...(noPadding ? { padding: 0 } : {}),
|
|
758
|
-
pointerEvents:
|
|
759
|
-
rootVisible && visible && !ignoreCardPointerEvents
|
|
760
|
-
? 'all'
|
|
761
|
-
: 'none',
|
|
762
|
-
}}
|
|
763
755
|
>
|
|
764
756
|
<div
|
|
765
757
|
className={cn(
|
|
766
758
|
'min-w-max transition-all duration-150 ease-[easing-function:cubic-bezier(0.3,_0.57,_0.07,_0.95)] will-change-[transform,width,height] motion-reduce:!transition-none',
|
|
767
759
|
skipTransition
|
|
768
760
|
? '!transition-none'
|
|
769
|
-
: 'transition-[transform,width,height] duration-
|
|
761
|
+
: 'transition-[transform,width,height] duration-[250ms] ease-[easing-function:cubic-bezier(0.29,0.31,0.05,0.96)] will-change-[transform,width,height] motion-reduce:!transition-none',
|
|
762
|
+
visible ? 'opacity-100' : 'opacity-0'
|
|
770
763
|
)}
|
|
771
764
|
ref={contentMeasureRef}
|
|
772
|
-
style={{
|
|
773
|
-
opacity: Number(visible),
|
|
774
|
-
}}
|
|
775
765
|
>
|
|
776
766
|
{content}
|
|
777
767
|
</div>
|