@assistant-ui/react-o11y 0.0.24 → 0.0.26
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/README.md +11 -3
- package/dist/context/SpanByIndexProvider.d.ts +0 -1
- package/dist/context/SpanByIndexProvider.d.ts.map +1 -1
- package/dist/o11y-scope.d.ts +1 -0
- package/dist/o11y-scope.d.ts.map +1 -1
- package/dist/primitives/span/SpanChildren.d.ts +2 -2
- package/dist/primitives/span/SpanChildren.d.ts.map +1 -1
- package/dist/primitives/span/SpanCollapseToggle.d.ts +0 -1
- package/dist/primitives/span/SpanCollapseToggle.d.ts.map +1 -1
- package/dist/primitives/span/SpanIndent.d.ts +0 -1
- package/dist/primitives/span/SpanIndent.d.ts.map +1 -1
- package/dist/primitives/span/SpanName.d.ts +0 -1
- package/dist/primitives/span/SpanName.d.ts.map +1 -1
- package/dist/primitives/span/SpanRoot.d.ts +0 -1
- package/dist/primitives/span/SpanRoot.d.ts.map +1 -1
- package/dist/primitives/span/SpanStatusIndicator.d.ts +0 -1
- package/dist/primitives/span/SpanStatusIndicator.d.ts.map +1 -1
- package/dist/primitives/span/SpanTimeline.d.ts +48 -0
- package/dist/primitives/span/SpanTimeline.d.ts.map +1 -0
- package/dist/primitives/span/SpanTimeline.js +215 -0
- package/dist/primitives/span/SpanTimeline.js.map +1 -0
- package/dist/primitives/span/SpanTypeBadge.d.ts +0 -1
- package/dist/primitives/span/SpanTypeBadge.d.ts.map +1 -1
- package/dist/primitives/span.d.ts +3 -4
- package/dist/primitives/span.js +4 -1
- package/dist/primitives/span.js.map +1 -1
- package/dist/resources/SpanResource.d.ts +1 -1
- package/dist/resources/SpanResource.d.ts.map +1 -1
- package/package.json +10 -6
- package/src/primitives/span/SpanTimeline.test.tsx +192 -0
- package/src/primitives/span/SpanTimeline.tsx +164 -0
- package/src/primitives/span.ts +5 -0
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ npm install @assistant-ui/react-o11y
|
|
|
14
14
|
"use client";
|
|
15
15
|
|
|
16
16
|
import { AuiProvider, useAui } from "@assistant-ui/store";
|
|
17
|
-
import { SpanResource } from "@assistant-ui/react-o11y";
|
|
17
|
+
import { SpanPrimitive, SpanResource } from "@assistant-ui/react-o11y";
|
|
18
18
|
|
|
19
19
|
const spans = [
|
|
20
20
|
{ id: "a", parentSpanId: null, name: "request", type: "http", status: "completed", startedAt: 0, endedAt: 120, latencyMs: 120 },
|
|
@@ -25,12 +25,20 @@ export function Waterfall() {
|
|
|
25
25
|
const aui = useAui({ span: SpanResource({ spans }) });
|
|
26
26
|
return (
|
|
27
27
|
<AuiProvider value={aui}>
|
|
28
|
-
|
|
28
|
+
<SpanPrimitive.Timeline>
|
|
29
|
+
<SpanPrimitive.Children>
|
|
30
|
+
{() => (
|
|
31
|
+
<div className="relative h-8">
|
|
32
|
+
<SpanPrimitive.TimelineBar className="top-1 h-6 rounded bg-blue-500" />
|
|
33
|
+
</div>
|
|
34
|
+
)}
|
|
35
|
+
</SpanPrimitive.Children>
|
|
36
|
+
</SpanPrimitive.Timeline>
|
|
29
37
|
</AuiProvider>
|
|
30
38
|
);
|
|
31
39
|
}
|
|
32
40
|
```
|
|
33
41
|
|
|
34
|
-
`SpanPrimitive.*` components rendered inside `<AuiProvider>` cover rows, indentation, names, status, and the
|
|
42
|
+
`SpanPrimitive.*` components rendered inside `<AuiProvider>` cover rows, indentation, names, status, collapse controls, and timeline bars. `SpanPrimitive.Timeline` provides the time range for its children; `SpanPrimitive.TimelineBar` positions each current span with CSS variables such as `--span-timeline-left` and `--span-timeline-width`. Running bars use the timeline range max unless you pass an explicit `now` timestamp from your own effect or animation loop.
|
|
35
43
|
|
|
36
44
|
See [`examples/waterfall`](https://github.com/assistant-ui/assistant-ui/tree/main/examples/waterfall) for a complete waterfall implementation.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SpanByIndexProvider.d.ts","names":[],"sources":["../../src/context/SpanByIndexProvider.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"SpanByIndexProvider.d.ts","names":[],"sources":["../../src/context/SpanByIndexProvider.tsx"],"mappings":";;cAGa,qBAAqB,GAAG;EAAoB"}
|
package/dist/o11y-scope.d.ts
CHANGED
package/dist/o11y-scope.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"o11y-scope.d.ts","names":[],"sources":["../src/o11y-scope.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"o11y-scope.d.ts","names":[],"sources":["../src/o11y-scope.ts"],"mappings":";;KAEY;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;KAGU,YAAY;EACtB,UAAU;EACV;IAAa;IAAa;;;KAGvB;EACH,gBAAgB;EAChB,QAAQ,QAAQ,sBAAsB;EACtC;;KAGG;EACH;EACA;IAAS;;IAAoB;;;;YAInB;IACR;MACE,SAAS;MACT,MAAM"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { SpanState } from "../../o11y-scope.js";
|
|
2
2
|
import { ComponentType, FC, ReactNode } from "react";
|
|
3
|
-
|
|
4
3
|
//#region src/primitives/span/SpanChildren.d.ts
|
|
5
4
|
type SpanChildrenComponentConfig = {
|
|
6
5
|
Span: ComponentType;
|
|
@@ -10,7 +9,8 @@ declare namespace SpanPrimitiveChildren {
|
|
|
10
9
|
components: SpanChildrenComponentConfig;
|
|
11
10
|
children?: never;
|
|
12
11
|
} | {
|
|
13
|
-
/** Render function called for each child span. Receives the span. */
|
|
12
|
+
/** Render function called for each child span. Receives the span. */
|
|
13
|
+
children: (value: {
|
|
14
14
|
span: SpanState;
|
|
15
15
|
}) => ReactNode;
|
|
16
16
|
components?: never;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SpanChildren.d.ts","names":[],"sources":["../../../src/primitives/span/SpanChildren.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"SpanChildren.d.ts","names":[],"sources":["../../../src/primitives/span/SpanChildren.tsx"],"mappings":";;;KAWK;EACH,MAAM;;kBAGS;OACH;IAEN,YAAY;IACZ;;;IAIA,WAAW;MAAS,MAAM;UAAgB;IAC1C;;;kBAIS;OACH;IACV;IACA,YAAY;;;cAIH,2BAA2B,GAAG,0BAA0B;cAuDxD,uBAAuB,GAAG,sBAAsB"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ComponentPropsWithoutRef, ComponentRef } from "react";
|
|
2
2
|
import { Primitive } from "@radix-ui/react-primitive";
|
|
3
|
-
|
|
4
3
|
//#region src/primitives/span/SpanCollapseToggle.d.ts
|
|
5
4
|
declare namespace SpanPrimitiveCollapseToggle {
|
|
6
5
|
type Element = ComponentRef<typeof Primitive.button>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SpanCollapseToggle.d.ts","names":[],"sources":["../../../src/primitives/span/SpanCollapseToggle.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"SpanCollapseToggle.d.ts","names":[],"sources":["../../../src/primitives/span/SpanCollapseToggle.tsx"],"mappings":";;;kBAQiB;OACH,UAAU,oBAAoB,UAAU;OACxC,QAAQ,gCAAgC,UAAU;;cAGnD,6CAA2B,0BAAA,qBAAA,gBAAA,qCAAA,qBAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SpanIndent.d.ts","names":[],"sources":["../../../src/primitives/span/SpanIndent.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"SpanIndent.d.ts","names":[],"sources":["../../../src/primitives/span/SpanIndent.tsx"],"mappings":";;;kBASiB;OACH,UAAU,oBAAoB,UAAU;OACxC,QAAQ,gCAAgC,UAAU;IAC5D;IACA;;;cAIS,qCAAmB,0BAAA,qBAAA,gBAAA,kCAAA,eAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SpanName.d.ts","names":[],"sources":["../../../src/primitives/span/SpanName.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"SpanName.d.ts","names":[],"sources":["../../../src/primitives/span/SpanName.tsx"],"mappings":";;;kBAQiB;OACH,UAAU,oBAAoB,UAAU;OACxC,QAAQ,gCAAgC,UAAU;;cAGnD,mCAAiB,0BAAA,qBAAA,gBAAA,mCAAA,eAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SpanRoot.d.ts","names":[],"sources":["../../../src/primitives/span/SpanRoot.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"SpanRoot.d.ts","names":[],"sources":["../../../src/primitives/span/SpanRoot.tsx"],"mappings":";;;kBAQiB;OACH,UAAU,oBAAoB,UAAU;OACxC,QAAQ,gCAAgC,UAAU;;cAGnD,mCAAiB,0BAAA,qBAAA,gBAAA,kCAAA,eAAA"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ComponentPropsWithoutRef, ComponentRef } from "react";
|
|
2
2
|
import { Primitive } from "@radix-ui/react-primitive";
|
|
3
|
-
|
|
4
3
|
//#region src/primitives/span/SpanStatusIndicator.d.ts
|
|
5
4
|
declare namespace SpanPrimitiveStatusIndicator {
|
|
6
5
|
type Element = ComponentRef<typeof Primitive.span>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SpanStatusIndicator.d.ts","names":[],"sources":["../../../src/primitives/span/SpanStatusIndicator.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"SpanStatusIndicator.d.ts","names":[],"sources":["../../../src/primitives/span/SpanStatusIndicator.tsx"],"mappings":";;;kBAQiB;OACH,UAAU,oBAAoB,UAAU;OACxC,QAAQ,gCAAgC,UAAU;;cAGnD,8CAA4B,0BAAA,qBAAA,gBAAA,mCAAA,eAAA"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { ComponentPropsWithoutRef, ComponentRef } from "react";
|
|
2
|
+
import { Primitive } from "@radix-ui/react-primitive";
|
|
3
|
+
//#region src/primitives/span/SpanTimeline.d.ts
|
|
4
|
+
type SpanTimelineRange = {
|
|
5
|
+
min: number;
|
|
6
|
+
max: number;
|
|
7
|
+
};
|
|
8
|
+
declare namespace SpanPrimitiveTimeline {
|
|
9
|
+
type Element = ComponentRef<typeof Primitive.div>;
|
|
10
|
+
type Props = ComponentPropsWithoutRef<typeof Primitive.div> & {
|
|
11
|
+
timeRange?: SpanTimelineRange | undefined;
|
|
12
|
+
paddingEnd?: number | undefined;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
declare const SpanPrimitiveTimeline: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & {
|
|
16
|
+
asChild?: boolean;
|
|
17
|
+
}, "ref"> & {
|
|
18
|
+
timeRange?: SpanTimelineRange | undefined;
|
|
19
|
+
paddingEnd?: number | undefined;
|
|
20
|
+
} & import("react").RefAttributes<HTMLDivElement>>;
|
|
21
|
+
declare namespace SpanPrimitiveTimelineBar {
|
|
22
|
+
type Element = ComponentRef<typeof Primitive.div>;
|
|
23
|
+
type Props = ComponentPropsWithoutRef<typeof Primitive.div> & {
|
|
24
|
+
now?: number | undefined;
|
|
25
|
+
timeRange?: SpanTimelineRange | undefined;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
declare const getSpanTimelineBarVars: ({ startedAt, endedAt, timeRange, now }: {
|
|
29
|
+
startedAt: number;
|
|
30
|
+
endedAt: number | null;
|
|
31
|
+
timeRange: SpanTimelineRange;
|
|
32
|
+
now?: number | undefined;
|
|
33
|
+
}) => {
|
|
34
|
+
leftPercent: number;
|
|
35
|
+
endPercent: number;
|
|
36
|
+
widthPercent: number;
|
|
37
|
+
durationMs: number;
|
|
38
|
+
effectiveEnd: number;
|
|
39
|
+
};
|
|
40
|
+
declare const SpanPrimitiveTimelineBar: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & {
|
|
41
|
+
asChild?: boolean;
|
|
42
|
+
}, "ref"> & {
|
|
43
|
+
now?: number | undefined;
|
|
44
|
+
timeRange?: SpanTimelineRange | undefined;
|
|
45
|
+
} & import("react").RefAttributes<HTMLDivElement>>;
|
|
46
|
+
//#endregion
|
|
47
|
+
export { SpanPrimitiveTimeline, SpanPrimitiveTimelineBar, SpanTimelineRange, getSpanTimelineBarVars };
|
|
48
|
+
//# sourceMappingURL=SpanTimeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpanTimeline.d.ts","names":[],"sources":["../../../src/primitives/span/SpanTimeline.tsx"],"mappings":";;;KAYY;EAAsB;EAAa;;kBA6B9B;OACH,UAAU,oBAAoB,UAAU;OACxC,QAAQ,gCAAgC,UAAU;IAC5D,YAAY;IACZ;;;cAIS,uCAAqB,0BAAA,qBAAA,gBAAA,kCAAA,eAAA;;;cALlB;;;kBAuCC;OACH,UAAU,oBAAoB,UAAU;OACxC,QAAQ,gCAAgC,UAAU;IAC5D;IACA,YAAY;;;cAIH,2BAA0B,WAAA,SAAA,WAAA;EAMrC;EACA;EACA,WAAW;EACX;;;;;;;;cAqBW,0CAAwB,0BAAA,qBAAA,gBAAA,kCAAA,eAAA;;;;cAlCrB"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
|
|
2
|
+
import { createContext, forwardRef, useContext } from "@assistant-ui/tap/react-shim";
|
|
3
|
+
import { Primitive } from "@radix-ui/react-primitive";
|
|
4
|
+
import { useAuiState } from "@assistant-ui/store";
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
//#region src/primitives/span/SpanTimeline.tsx
|
|
7
|
+
const clampPercent = (value) => Math.min(100, Math.max(0, value));
|
|
8
|
+
const normalizeRange = (range, paddingEnd = 0) => {
|
|
9
|
+
const duration = Math.max(1, range.max - range.min);
|
|
10
|
+
const safePaddingEnd = Math.max(0, paddingEnd);
|
|
11
|
+
return {
|
|
12
|
+
min: range.min,
|
|
13
|
+
max: range.max + duration * safePaddingEnd
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
const SpanTimelineRangeContext = createContext(null);
|
|
17
|
+
const SpanPrimitiveTimeline = forwardRef((t0, ref) => {
|
|
18
|
+
const $ = c(22);
|
|
19
|
+
let children;
|
|
20
|
+
let props;
|
|
21
|
+
let style;
|
|
22
|
+
let t1;
|
|
23
|
+
let timeRange;
|
|
24
|
+
if ($[0] !== t0) {
|
|
25
|
+
({timeRange, paddingEnd: t1, style, children, ...props} = t0);
|
|
26
|
+
$[0] = t0;
|
|
27
|
+
$[1] = children;
|
|
28
|
+
$[2] = props;
|
|
29
|
+
$[3] = style;
|
|
30
|
+
$[4] = t1;
|
|
31
|
+
$[5] = timeRange;
|
|
32
|
+
} else {
|
|
33
|
+
children = $[1];
|
|
34
|
+
props = $[2];
|
|
35
|
+
style = $[3];
|
|
36
|
+
t1 = $[4];
|
|
37
|
+
timeRange = $[5];
|
|
38
|
+
}
|
|
39
|
+
const paddingEnd = t1 === void 0 ? 0 : t1;
|
|
40
|
+
const spanTimeRange = useAuiState(_temp);
|
|
41
|
+
const t2 = timeRange ?? spanTimeRange;
|
|
42
|
+
let t3;
|
|
43
|
+
if ($[6] !== paddingEnd || $[7] !== t2) {
|
|
44
|
+
t3 = normalizeRange(t2, paddingEnd);
|
|
45
|
+
$[6] = paddingEnd;
|
|
46
|
+
$[7] = t2;
|
|
47
|
+
$[8] = t3;
|
|
48
|
+
} else t3 = $[8];
|
|
49
|
+
const resolvedRange = t3;
|
|
50
|
+
const rangeMs = Math.max(1, resolvedRange.max - resolvedRange.min);
|
|
51
|
+
let t4;
|
|
52
|
+
if ($[9] !== rangeMs || $[10] !== resolvedRange.max || $[11] !== resolvedRange.min || $[12] !== style) {
|
|
53
|
+
t4 = {
|
|
54
|
+
...style,
|
|
55
|
+
"--span-timeline-min-ms": resolvedRange.min,
|
|
56
|
+
"--span-timeline-max-ms": resolvedRange.max,
|
|
57
|
+
"--span-timeline-range-ms": rangeMs
|
|
58
|
+
};
|
|
59
|
+
$[9] = rangeMs;
|
|
60
|
+
$[10] = resolvedRange.max;
|
|
61
|
+
$[11] = resolvedRange.min;
|
|
62
|
+
$[12] = style;
|
|
63
|
+
$[13] = t4;
|
|
64
|
+
} else t4 = $[13];
|
|
65
|
+
const mergedStyle = t4;
|
|
66
|
+
let t5;
|
|
67
|
+
if ($[14] !== children || $[15] !== mergedStyle || $[16] !== props || $[17] !== ref) {
|
|
68
|
+
t5 = /* @__PURE__ */ jsx(Primitive.div, {
|
|
69
|
+
...props,
|
|
70
|
+
ref,
|
|
71
|
+
style: mergedStyle,
|
|
72
|
+
"data-span-timeline": "",
|
|
73
|
+
children
|
|
74
|
+
});
|
|
75
|
+
$[14] = children;
|
|
76
|
+
$[15] = mergedStyle;
|
|
77
|
+
$[16] = props;
|
|
78
|
+
$[17] = ref;
|
|
79
|
+
$[18] = t5;
|
|
80
|
+
} else t5 = $[18];
|
|
81
|
+
let t6;
|
|
82
|
+
if ($[19] !== resolvedRange || $[20] !== t5) {
|
|
83
|
+
t6 = /* @__PURE__ */ jsx(SpanTimelineRangeContext.Provider, {
|
|
84
|
+
value: resolvedRange,
|
|
85
|
+
children: t5
|
|
86
|
+
});
|
|
87
|
+
$[19] = resolvedRange;
|
|
88
|
+
$[20] = t5;
|
|
89
|
+
$[21] = t6;
|
|
90
|
+
} else t6 = $[21];
|
|
91
|
+
return t6;
|
|
92
|
+
});
|
|
93
|
+
SpanPrimitiveTimeline.displayName = "SpanPrimitive.Timeline";
|
|
94
|
+
const getSpanTimelineBarVars = ({ startedAt, endedAt, timeRange, now }) => {
|
|
95
|
+
const rangeMs = Math.max(1, timeRange.max - timeRange.min);
|
|
96
|
+
const effectiveEnd = endedAt ?? now ?? timeRange.max;
|
|
97
|
+
const leftPercent = clampPercent((startedAt - timeRange.min) / rangeMs * 100);
|
|
98
|
+
const rawEndPercent = (effectiveEnd - timeRange.min) / rangeMs * 100;
|
|
99
|
+
const endPercent = clampPercent(Math.max(leftPercent, rawEndPercent));
|
|
100
|
+
return {
|
|
101
|
+
leftPercent,
|
|
102
|
+
endPercent,
|
|
103
|
+
widthPercent: endPercent - leftPercent,
|
|
104
|
+
durationMs: Math.max(0, effectiveEnd - startedAt),
|
|
105
|
+
effectiveEnd
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
const SpanPrimitiveTimelineBar = forwardRef((t0, ref) => {
|
|
109
|
+
const $ = c(23);
|
|
110
|
+
let now;
|
|
111
|
+
let props;
|
|
112
|
+
let style;
|
|
113
|
+
let timeRange;
|
|
114
|
+
if ($[0] !== t0) {
|
|
115
|
+
({now, timeRange, style, ...props} = t0);
|
|
116
|
+
$[0] = t0;
|
|
117
|
+
$[1] = now;
|
|
118
|
+
$[2] = props;
|
|
119
|
+
$[3] = style;
|
|
120
|
+
$[4] = timeRange;
|
|
121
|
+
} else {
|
|
122
|
+
now = $[1];
|
|
123
|
+
props = $[2];
|
|
124
|
+
style = $[3];
|
|
125
|
+
timeRange = $[4];
|
|
126
|
+
}
|
|
127
|
+
const contextRange = useContext(SpanTimelineRangeContext);
|
|
128
|
+
const spanTimeRange = useAuiState(_temp2);
|
|
129
|
+
const startedAt = useAuiState(_temp3);
|
|
130
|
+
const endedAt = useAuiState(_temp4);
|
|
131
|
+
const status = useAuiState(_temp5);
|
|
132
|
+
const type = useAuiState(_temp6);
|
|
133
|
+
const t1 = timeRange ?? contextRange ?? spanTimeRange;
|
|
134
|
+
let t2;
|
|
135
|
+
if ($[5] !== endedAt || $[6] !== now || $[7] !== startedAt || $[8] !== t1) {
|
|
136
|
+
t2 = getSpanTimelineBarVars({
|
|
137
|
+
startedAt,
|
|
138
|
+
endedAt,
|
|
139
|
+
timeRange: t1,
|
|
140
|
+
now
|
|
141
|
+
});
|
|
142
|
+
$[5] = endedAt;
|
|
143
|
+
$[6] = now;
|
|
144
|
+
$[7] = startedAt;
|
|
145
|
+
$[8] = t1;
|
|
146
|
+
$[9] = t2;
|
|
147
|
+
} else t2 = $[9];
|
|
148
|
+
const vars = t2;
|
|
149
|
+
const t3 = `${vars.leftPercent}%`;
|
|
150
|
+
const t4 = `${vars.endPercent}%`;
|
|
151
|
+
const t5 = `${vars.widthPercent}%`;
|
|
152
|
+
let t6;
|
|
153
|
+
if ($[10] !== style || $[11] !== t3 || $[12] !== t4 || $[13] !== t5 || $[14] !== vars.durationMs) {
|
|
154
|
+
t6 = {
|
|
155
|
+
...style,
|
|
156
|
+
position: "absolute",
|
|
157
|
+
insetInlineStart: "var(--span-timeline-left)",
|
|
158
|
+
inlineSize: "max(var(--span-timeline-width), var(--span-timeline-min-width, 0px))",
|
|
159
|
+
"--span-timeline-left": t3,
|
|
160
|
+
"--span-timeline-end": t4,
|
|
161
|
+
"--span-timeline-width": t5,
|
|
162
|
+
"--span-timeline-duration-ms": vars.durationMs
|
|
163
|
+
};
|
|
164
|
+
$[10] = style;
|
|
165
|
+
$[11] = t3;
|
|
166
|
+
$[12] = t4;
|
|
167
|
+
$[13] = t5;
|
|
168
|
+
$[14] = vars.durationMs;
|
|
169
|
+
$[15] = t6;
|
|
170
|
+
} else t6 = $[15];
|
|
171
|
+
const mergedStyle = t6;
|
|
172
|
+
const t7 = endedAt === null ? "" : void 0;
|
|
173
|
+
let t8;
|
|
174
|
+
if ($[16] !== mergedStyle || $[17] !== props || $[18] !== ref || $[19] !== status || $[20] !== t7 || $[21] !== type) {
|
|
175
|
+
t8 = /* @__PURE__ */ jsx(Primitive.div, {
|
|
176
|
+
...props,
|
|
177
|
+
ref,
|
|
178
|
+
style: mergedStyle,
|
|
179
|
+
"data-span-status": status,
|
|
180
|
+
"data-span-type": type,
|
|
181
|
+
"data-span-running": t7
|
|
182
|
+
});
|
|
183
|
+
$[16] = mergedStyle;
|
|
184
|
+
$[17] = props;
|
|
185
|
+
$[18] = ref;
|
|
186
|
+
$[19] = status;
|
|
187
|
+
$[20] = t7;
|
|
188
|
+
$[21] = type;
|
|
189
|
+
$[22] = t8;
|
|
190
|
+
} else t8 = $[22];
|
|
191
|
+
return t8;
|
|
192
|
+
});
|
|
193
|
+
SpanPrimitiveTimelineBar.displayName = "SpanPrimitive.TimelineBar";
|
|
194
|
+
function _temp(s) {
|
|
195
|
+
return s.span.timeRange;
|
|
196
|
+
}
|
|
197
|
+
function _temp2(s) {
|
|
198
|
+
return s.span.timeRange;
|
|
199
|
+
}
|
|
200
|
+
function _temp3(s_0) {
|
|
201
|
+
return s_0.span.startedAt;
|
|
202
|
+
}
|
|
203
|
+
function _temp4(s_1) {
|
|
204
|
+
return s_1.span.endedAt;
|
|
205
|
+
}
|
|
206
|
+
function _temp5(s_2) {
|
|
207
|
+
return s_2.span.status;
|
|
208
|
+
}
|
|
209
|
+
function _temp6(s_3) {
|
|
210
|
+
return s_3.span.type;
|
|
211
|
+
}
|
|
212
|
+
//#endregion
|
|
213
|
+
export { SpanPrimitiveTimeline, SpanPrimitiveTimelineBar, getSpanTimelineBarVars };
|
|
214
|
+
|
|
215
|
+
//# sourceMappingURL=SpanTimeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpanTimeline.js","names":["ComponentPropsWithoutRef","ComponentRef","CSSProperties","createContext","forwardRef","useContext","useMemo","Primitive","useAuiState","SpanTimelineRange","min","max","TimelineCssProperties","clampPercent","value","Math","normalizeRange","range","paddingEnd","duration","safePaddingEnd","SpanTimelineRangeContext","SpanPrimitiveTimeline","Element","div","Props","timeRange","t0","ref","$","_c","children","props","style","t1","undefined","spanTimeRange","_temp","t2","t3","resolvedRange","rangeMs","t4","mergedStyle","t5","t6","displayName","SpanPrimitiveTimelineBar","now","getSpanTimelineBarVars","startedAt","endedAt","effectiveEnd","leftPercent","rawEndPercent","endPercent","widthPercent","durationMs","contextRange","_temp2","_temp3","_temp4","status","_temp5","type","_temp6","vars","position","insetInlineStart","inlineSize","t7","t8","s","span","s_0","s_1","s_2","s_3"],"sources":["../../../src/primitives/span/SpanTimeline.tsx"],"sourcesContent":["import {\n type ComponentPropsWithoutRef,\n type ComponentRef,\n type CSSProperties,\n createContext,\n forwardRef,\n useContext,\n useMemo,\n} from \"react\";\nimport { Primitive } from \"@radix-ui/react-primitive\";\nimport { useAuiState } from \"@assistant-ui/store\";\n\nexport type SpanTimelineRange = { min: number; max: number };\n\ntype TimelineCssProperties = CSSProperties & {\n \"--span-timeline-min-ms\"?: number;\n \"--span-timeline-max-ms\"?: number;\n \"--span-timeline-range-ms\"?: number;\n \"--span-timeline-left\"?: string;\n \"--span-timeline-end\"?: string;\n \"--span-timeline-width\"?: string;\n \"--span-timeline-duration-ms\"?: number;\n \"--span-timeline-min-width\"?: string | number;\n};\n\nconst clampPercent = (value: number) => Math.min(100, Math.max(0, value));\n\nconst normalizeRange = (\n range: SpanTimelineRange,\n paddingEnd = 0,\n): SpanTimelineRange => {\n const duration = Math.max(1, range.max - range.min);\n const safePaddingEnd = Math.max(0, paddingEnd);\n return {\n min: range.min,\n max: range.max + duration * safePaddingEnd,\n };\n};\n\nconst SpanTimelineRangeContext = createContext<SpanTimelineRange | null>(null);\n\nexport namespace SpanPrimitiveTimeline {\n export type Element = ComponentRef<typeof Primitive.div>;\n export type Props = ComponentPropsWithoutRef<typeof Primitive.div> & {\n timeRange?: SpanTimelineRange | undefined;\n paddingEnd?: number | undefined;\n };\n}\n\nexport const SpanPrimitiveTimeline = forwardRef<\n SpanPrimitiveTimeline.Element,\n SpanPrimitiveTimeline.Props\n>(({ timeRange, paddingEnd = 0, style, children, ...props }, ref) => {\n const spanTimeRange = useAuiState((s) => s.span.timeRange);\n const resolvedRange = useMemo(\n () => normalizeRange(timeRange ?? spanTimeRange, paddingEnd),\n [timeRange, spanTimeRange, paddingEnd],\n );\n const rangeMs = Math.max(1, resolvedRange.max - resolvedRange.min);\n\n const mergedStyle: TimelineCssProperties = {\n ...style,\n \"--span-timeline-min-ms\": resolvedRange.min,\n \"--span-timeline-max-ms\": resolvedRange.max,\n \"--span-timeline-range-ms\": rangeMs,\n };\n\n return (\n <SpanTimelineRangeContext.Provider value={resolvedRange}>\n <Primitive.div\n {...props}\n ref={ref}\n style={mergedStyle}\n data-span-timeline=\"\"\n >\n {children}\n </Primitive.div>\n </SpanTimelineRangeContext.Provider>\n );\n});\n\nSpanPrimitiveTimeline.displayName = \"SpanPrimitive.Timeline\";\n\nexport namespace SpanPrimitiveTimelineBar {\n export type Element = ComponentRef<typeof Primitive.div>;\n export type Props = ComponentPropsWithoutRef<typeof Primitive.div> & {\n now?: number | undefined;\n timeRange?: SpanTimelineRange | undefined;\n };\n}\n\nexport const getSpanTimelineBarVars = ({\n startedAt,\n endedAt,\n timeRange,\n now,\n}: {\n startedAt: number;\n endedAt: number | null;\n timeRange: SpanTimelineRange;\n now?: number | undefined;\n}) => {\n const rangeMs = Math.max(1, timeRange.max - timeRange.min);\n const effectiveEnd = endedAt ?? now ?? timeRange.max;\n const leftPercent = clampPercent(\n ((startedAt - timeRange.min) / rangeMs) * 100,\n );\n const rawEndPercent = ((effectiveEnd - timeRange.min) / rangeMs) * 100;\n const endPercent = clampPercent(Math.max(leftPercent, rawEndPercent));\n const widthPercent = endPercent - leftPercent;\n const durationMs = Math.max(0, effectiveEnd - startedAt);\n\n return {\n leftPercent,\n endPercent,\n widthPercent,\n durationMs,\n effectiveEnd,\n };\n};\n\nexport const SpanPrimitiveTimelineBar = forwardRef<\n SpanPrimitiveTimelineBar.Element,\n SpanPrimitiveTimelineBar.Props\n>(({ now, timeRange, style, ...props }, ref) => {\n const contextRange = useContext(SpanTimelineRangeContext);\n const spanTimeRange = useAuiState((s) => s.span.timeRange);\n const startedAt = useAuiState((s) => s.span.startedAt);\n const endedAt = useAuiState((s) => s.span.endedAt);\n const status = useAuiState((s) => s.span.status);\n const type = useAuiState((s) => s.span.type);\n\n const vars = getSpanTimelineBarVars({\n startedAt,\n endedAt,\n timeRange: timeRange ?? contextRange ?? spanTimeRange,\n now,\n });\n\n const mergedStyle: TimelineCssProperties = {\n ...style,\n position: \"absolute\",\n insetInlineStart: \"var(--span-timeline-left)\",\n inlineSize:\n \"max(var(--span-timeline-width), var(--span-timeline-min-width, 0px))\",\n \"--span-timeline-left\": `${vars.leftPercent}%`,\n \"--span-timeline-end\": `${vars.endPercent}%`,\n \"--span-timeline-width\": `${vars.widthPercent}%`,\n \"--span-timeline-duration-ms\": vars.durationMs,\n };\n\n return (\n <Primitive.div\n {...props}\n ref={ref}\n style={mergedStyle}\n data-span-status={status}\n data-span-type={type}\n data-span-running={endedAt === null ? \"\" : undefined}\n />\n );\n});\n\nSpanPrimitiveTimelineBar.displayName = \"SpanPrimitive.TimelineBar\";\n"],"mappings":"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"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ComponentPropsWithoutRef, ComponentRef } from "react";
|
|
2
2
|
import { Primitive } from "@radix-ui/react-primitive";
|
|
3
|
-
|
|
4
3
|
//#region src/primitives/span/SpanTypeBadge.d.ts
|
|
5
4
|
declare namespace SpanPrimitiveTypeBadge {
|
|
6
5
|
type Element = ComponentRef<typeof Primitive.span>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SpanTypeBadge.d.ts","names":[],"sources":["../../../src/primitives/span/SpanTypeBadge.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"SpanTypeBadge.d.ts","names":[],"sources":["../../../src/primitives/span/SpanTypeBadge.tsx"],"mappings":";;;kBAQiB;OACH,UAAU,oBAAoB,UAAU;OACxC,QAAQ,gCAAgC,UAAU;;cAGnD,wCAAsB,0BAAA,qBAAA,gBAAA,mCAAA,eAAA"}
|
|
@@ -5,11 +5,10 @@ import { SpanPrimitiveStatusIndicator } from "./span/SpanStatusIndicator.js";
|
|
|
5
5
|
import { SpanPrimitiveCollapseToggle } from "./span/SpanCollapseToggle.js";
|
|
6
6
|
import { SpanPrimitiveIndent } from "./span/SpanIndent.js";
|
|
7
7
|
import { SpanPrimitiveChildren } from "./span/SpanChildren.js";
|
|
8
|
-
|
|
9
|
-
//#region src/primitives/span.d.ts
|
|
8
|
+
import { SpanPrimitiveTimeline, SpanPrimitiveTimelineBar, SpanTimelineRange } from "./span/SpanTimeline.js";
|
|
10
9
|
declare namespace span_d_exports {
|
|
11
|
-
export { SpanPrimitiveChildren as Children, SpanPrimitiveCollapseToggle as CollapseToggle, SpanPrimitiveIndent as Indent, SpanPrimitiveName as Name, SpanPrimitiveRoot as Root, SpanPrimitiveStatusIndicator as StatusIndicator, SpanPrimitiveTypeBadge as TypeBadge };
|
|
10
|
+
export { SpanPrimitiveChildren as Children, SpanPrimitiveCollapseToggle as CollapseToggle, SpanPrimitiveIndent as Indent, SpanPrimitiveName as Name, SpanPrimitiveRoot as Root, SpanTimelineRange, SpanPrimitiveStatusIndicator as StatusIndicator, SpanPrimitiveTimeline as Timeline, SpanPrimitiveTimelineBar as TimelineBar, SpanPrimitiveTypeBadge as TypeBadge };
|
|
12
11
|
}
|
|
13
12
|
//#endregion
|
|
14
|
-
export { SpanPrimitiveChildren as Children, SpanPrimitiveCollapseToggle as CollapseToggle, SpanPrimitiveIndent as Indent, SpanPrimitiveName as Name, SpanPrimitiveRoot as Root, SpanPrimitiveStatusIndicator as StatusIndicator, SpanPrimitiveTypeBadge as TypeBadge, span_d_exports };
|
|
13
|
+
export { SpanPrimitiveChildren as Children, SpanPrimitiveCollapseToggle as CollapseToggle, SpanPrimitiveIndent as Indent, SpanPrimitiveName as Name, SpanPrimitiveRoot as Root, type SpanTimelineRange, SpanPrimitiveStatusIndicator as StatusIndicator, SpanPrimitiveTimeline as Timeline, SpanPrimitiveTimelineBar as TimelineBar, SpanPrimitiveTypeBadge as TypeBadge, span_d_exports };
|
|
15
14
|
//# sourceMappingURL=span.d.ts.map
|
package/dist/primitives/span.js
CHANGED
|
@@ -6,6 +6,7 @@ import { SpanPrimitiveStatusIndicator } from "./span/SpanStatusIndicator.js";
|
|
|
6
6
|
import { SpanPrimitiveCollapseToggle } from "./span/SpanCollapseToggle.js";
|
|
7
7
|
import { SpanPrimitiveIndent } from "./span/SpanIndent.js";
|
|
8
8
|
import { SpanPrimitiveChildren } from "./span/SpanChildren.js";
|
|
9
|
+
import { SpanPrimitiveTimeline, SpanPrimitiveTimelineBar } from "./span/SpanTimeline.js";
|
|
9
10
|
//#region src/primitives/span.ts
|
|
10
11
|
var span_exports = /* @__PURE__ */ __exportAll({
|
|
11
12
|
Children: () => SpanPrimitiveChildren,
|
|
@@ -14,9 +15,11 @@ var span_exports = /* @__PURE__ */ __exportAll({
|
|
|
14
15
|
Name: () => SpanPrimitiveName,
|
|
15
16
|
Root: () => SpanPrimitiveRoot,
|
|
16
17
|
StatusIndicator: () => SpanPrimitiveStatusIndicator,
|
|
18
|
+
Timeline: () => SpanPrimitiveTimeline,
|
|
19
|
+
TimelineBar: () => SpanPrimitiveTimelineBar,
|
|
17
20
|
TypeBadge: () => SpanPrimitiveTypeBadge
|
|
18
21
|
});
|
|
19
22
|
//#endregion
|
|
20
|
-
export { SpanPrimitiveChildren as Children, SpanPrimitiveCollapseToggle as CollapseToggle, SpanPrimitiveIndent as Indent, SpanPrimitiveName as Name, SpanPrimitiveRoot as Root, SpanPrimitiveStatusIndicator as StatusIndicator, SpanPrimitiveTypeBadge as TypeBadge, span_exports };
|
|
23
|
+
export { SpanPrimitiveChildren as Children, SpanPrimitiveCollapseToggle as CollapseToggle, SpanPrimitiveIndent as Indent, SpanPrimitiveName as Name, SpanPrimitiveRoot as Root, SpanPrimitiveStatusIndicator as StatusIndicator, SpanPrimitiveTimeline as Timeline, SpanPrimitiveTimelineBar as TimelineBar, SpanPrimitiveTypeBadge as TypeBadge, span_exports };
|
|
21
24
|
|
|
22
25
|
//# sourceMappingURL=span.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"span.js","names":["SpanPrimitiveRoot","Root","SpanPrimitiveName","Name","SpanPrimitiveTypeBadge","TypeBadge","SpanPrimitiveStatusIndicator","StatusIndicator","SpanPrimitiveCollapseToggle","CollapseToggle","SpanPrimitiveIndent","Indent","SpanPrimitiveChildren","Children"],"sources":["../../src/primitives/span.ts"],"sourcesContent":["export { SpanPrimitiveRoot as Root } from \"./span/SpanRoot\";\nexport { SpanPrimitiveName as Name } from \"./span/SpanName\";\nexport { SpanPrimitiveTypeBadge as TypeBadge } from \"./span/SpanTypeBadge\";\nexport { SpanPrimitiveStatusIndicator as StatusIndicator } from \"./span/SpanStatusIndicator\";\nexport { SpanPrimitiveCollapseToggle as CollapseToggle } from \"./span/SpanCollapseToggle\";\nexport { SpanPrimitiveIndent as Indent } from \"./span/SpanIndent\";\nexport { SpanPrimitiveChildren as Children } from \"./span/SpanChildren\";\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"span.js","names":["SpanPrimitiveRoot","Root","SpanPrimitiveName","Name","SpanPrimitiveTypeBadge","TypeBadge","SpanPrimitiveStatusIndicator","StatusIndicator","SpanPrimitiveCollapseToggle","CollapseToggle","SpanPrimitiveIndent","Indent","SpanPrimitiveChildren","Children","SpanPrimitiveTimeline","Timeline","SpanPrimitiveTimelineBar","TimelineBar","SpanTimelineRange"],"sources":["../../src/primitives/span.ts"],"sourcesContent":["export { SpanPrimitiveRoot as Root } from \"./span/SpanRoot\";\nexport { SpanPrimitiveName as Name } from \"./span/SpanName\";\nexport { SpanPrimitiveTypeBadge as TypeBadge } from \"./span/SpanTypeBadge\";\nexport { SpanPrimitiveStatusIndicator as StatusIndicator } from \"./span/SpanStatusIndicator\";\nexport { SpanPrimitiveCollapseToggle as CollapseToggle } from \"./span/SpanCollapseToggle\";\nexport { SpanPrimitiveIndent as Indent } from \"./span/SpanIndent\";\nexport { SpanPrimitiveChildren as Children } from \"./span/SpanChildren\";\nexport {\n SpanPrimitiveTimeline as Timeline,\n SpanPrimitiveTimelineBar as TimelineBar,\n type SpanTimelineRange,\n} from \"./span/SpanTimeline\";\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SpanResource.d.ts","names":[],"sources":["../../src/resources/SpanResource.tsx"],"mappings":";;;KAOY
|
|
1
|
+
{"version":3,"file":"SpanResource.d.ts","names":[],"sources":["../../src/resources/SpanResource.tsx"],"mappings":";;;KAOY;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;cA8LW,0CAAY,SAAA;SA/DhB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assistant-ui/react-o11y",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.26",
|
|
4
4
|
"description": "Observability primitives for @assistant-ui",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"observability",
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
],
|
|
29
29
|
"sideEffects": false,
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@radix-ui/react-primitive": "^2.1.
|
|
32
|
-
"@assistant-ui/store": "0.2.
|
|
33
|
-
"@assistant-ui/tap": "0.9.
|
|
31
|
+
"@radix-ui/react-primitive": "^2.1.7",
|
|
32
|
+
"@assistant-ui/store": "0.2.20",
|
|
33
|
+
"@assistant-ui/tap": "0.9.4"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"@types/react": "*",
|
|
@@ -43,8 +43,11 @@
|
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@types/react": "^19.2.17",
|
|
46
|
+
"@types/react-dom": "^19.2.3",
|
|
46
47
|
"react": "^19.2.7",
|
|
47
|
-
"
|
|
48
|
+
"react-dom": "^19.2.7",
|
|
49
|
+
"vitest": "^4.1.10",
|
|
50
|
+
"@assistant-ui/x-buildutils": "0.0.18"
|
|
48
51
|
},
|
|
49
52
|
"publishConfig": {
|
|
50
53
|
"access": "public",
|
|
@@ -60,6 +63,7 @@
|
|
|
60
63
|
"url": "https://github.com/assistant-ui/assistant-ui/issues"
|
|
61
64
|
},
|
|
62
65
|
"scripts": {
|
|
63
|
-
"build": "aui-build"
|
|
66
|
+
"build": "aui-build",
|
|
67
|
+
"test": "vitest run"
|
|
64
68
|
}
|
|
65
69
|
}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import type { CSSProperties } from "react";
|
|
2
|
+
import { renderToStaticMarkup } from "react-dom/server";
|
|
3
|
+
import { describe, expect, it, vi } from "vitest";
|
|
4
|
+
import { AuiProvider, useAui } from "@assistant-ui/store";
|
|
5
|
+
import * as SpanPrimitive from "../span";
|
|
6
|
+
import { SpanResource, type SpanData } from "../../resources/SpanResource";
|
|
7
|
+
import { getSpanTimelineBarVars } from "./SpanTimeline";
|
|
8
|
+
|
|
9
|
+
const spans: SpanData[] = [
|
|
10
|
+
{
|
|
11
|
+
id: "root",
|
|
12
|
+
parentSpanId: null,
|
|
13
|
+
name: "request",
|
|
14
|
+
type: "http",
|
|
15
|
+
status: "completed",
|
|
16
|
+
startedAt: 0,
|
|
17
|
+
endedAt: 100,
|
|
18
|
+
latencyMs: 100,
|
|
19
|
+
},
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
const TimelineFixture = ({
|
|
23
|
+
paddingEnd,
|
|
24
|
+
now,
|
|
25
|
+
barStyle,
|
|
26
|
+
}: {
|
|
27
|
+
paddingEnd?: number | undefined;
|
|
28
|
+
now?: number | undefined;
|
|
29
|
+
barStyle?: CSSProperties | undefined;
|
|
30
|
+
}) => {
|
|
31
|
+
const aui = useAui({ span: SpanResource({ spans }) });
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<AuiProvider value={aui}>
|
|
35
|
+
<SpanPrimitive.Timeline paddingEnd={paddingEnd}>
|
|
36
|
+
<SpanPrimitive.Children>
|
|
37
|
+
{() => <SpanPrimitive.TimelineBar now={now} style={barStyle} />}
|
|
38
|
+
</SpanPrimitive.Children>
|
|
39
|
+
</SpanPrimitive.Timeline>
|
|
40
|
+
</AuiProvider>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const runningSpans: SpanData[] = [
|
|
45
|
+
{
|
|
46
|
+
id: "root",
|
|
47
|
+
parentSpanId: null,
|
|
48
|
+
name: "request",
|
|
49
|
+
type: "http",
|
|
50
|
+
status: "running",
|
|
51
|
+
startedAt: 0,
|
|
52
|
+
endedAt: null,
|
|
53
|
+
latencyMs: null,
|
|
54
|
+
},
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
const RunningFixture = () => {
|
|
58
|
+
const aui = useAui({ span: SpanResource({ spans: runningSpans }) });
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<AuiProvider value={aui}>
|
|
62
|
+
<SpanPrimitive.Timeline timeRange={{ min: 0, max: 100 }}>
|
|
63
|
+
<SpanPrimitive.Children>
|
|
64
|
+
{() => <SpanPrimitive.TimelineBar />}
|
|
65
|
+
</SpanPrimitive.Children>
|
|
66
|
+
</SpanPrimitive.Timeline>
|
|
67
|
+
</AuiProvider>
|
|
68
|
+
);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
describe("SpanPrimitive.Timeline", () => {
|
|
72
|
+
it("computes stable timeline percentages for completed spans", () => {
|
|
73
|
+
expect(
|
|
74
|
+
getSpanTimelineBarVars({
|
|
75
|
+
startedAt: 25,
|
|
76
|
+
endedAt: 75,
|
|
77
|
+
timeRange: { min: 0, max: 100 },
|
|
78
|
+
}),
|
|
79
|
+
).toMatchObject({
|
|
80
|
+
leftPercent: 25,
|
|
81
|
+
endPercent: 75,
|
|
82
|
+
widthPercent: 50,
|
|
83
|
+
durationMs: 50,
|
|
84
|
+
effectiveEnd: 75,
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("uses now for running spans without producing negative widths", () => {
|
|
89
|
+
expect(
|
|
90
|
+
getSpanTimelineBarVars({
|
|
91
|
+
startedAt: 100,
|
|
92
|
+
endedAt: null,
|
|
93
|
+
timeRange: { min: 0, max: 200 },
|
|
94
|
+
now: 80,
|
|
95
|
+
}),
|
|
96
|
+
).toMatchObject({
|
|
97
|
+
leftPercent: 50,
|
|
98
|
+
endPercent: 50,
|
|
99
|
+
widthPercent: 0,
|
|
100
|
+
durationMs: 0,
|
|
101
|
+
effectiveEnd: 80,
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it("uses the range boundary for running spans when now is omitted", () => {
|
|
106
|
+
const dateNow = vi.spyOn(Date, "now").mockReturnValue(1_000);
|
|
107
|
+
|
|
108
|
+
expect(
|
|
109
|
+
getSpanTimelineBarVars({
|
|
110
|
+
startedAt: 25,
|
|
111
|
+
endedAt: null,
|
|
112
|
+
timeRange: { min: 0, max: 100 },
|
|
113
|
+
}),
|
|
114
|
+
).toMatchObject({
|
|
115
|
+
leftPercent: 25,
|
|
116
|
+
endPercent: 100,
|
|
117
|
+
widthPercent: 75,
|
|
118
|
+
durationMs: 75,
|
|
119
|
+
effectiveEnd: 100,
|
|
120
|
+
});
|
|
121
|
+
expect(dateNow).not.toHaveBeenCalled();
|
|
122
|
+
|
|
123
|
+
dateNow.mockRestore();
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it("clamps bar geometry to the timeline when now or startedAt fall outside the range", () => {
|
|
127
|
+
expect(
|
|
128
|
+
getSpanTimelineBarVars({
|
|
129
|
+
startedAt: 25,
|
|
130
|
+
endedAt: null,
|
|
131
|
+
timeRange: { min: 0, max: 100 },
|
|
132
|
+
now: 10_000,
|
|
133
|
+
}),
|
|
134
|
+
).toMatchObject({
|
|
135
|
+
leftPercent: 25,
|
|
136
|
+
endPercent: 100,
|
|
137
|
+
widthPercent: 75,
|
|
138
|
+
effectiveEnd: 10_000,
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
expect(
|
|
142
|
+
getSpanTimelineBarVars({
|
|
143
|
+
startedAt: -50,
|
|
144
|
+
endedAt: 50,
|
|
145
|
+
timeRange: { min: 0, max: 100 },
|
|
146
|
+
}),
|
|
147
|
+
).toMatchObject({
|
|
148
|
+
leftPercent: 0,
|
|
149
|
+
endPercent: 50,
|
|
150
|
+
widthPercent: 50,
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it("provides the padded timeline range to child bars", () => {
|
|
155
|
+
const html = renderToStaticMarkup(<TimelineFixture paddingEnd={1} />);
|
|
156
|
+
|
|
157
|
+
expect(html).toContain("data-span-timeline");
|
|
158
|
+
expect(html).toContain("--span-timeline-range-ms:200");
|
|
159
|
+
expect(html).toContain("--span-timeline-width:50%");
|
|
160
|
+
expect(html).toContain('data-span-status="completed"');
|
|
161
|
+
expect(html).toContain('data-span-type="http"');
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it("marks running bars with data-span-running and omits it for completed spans", () => {
|
|
165
|
+
expect(renderToStaticMarkup(<RunningFixture />)).toContain(
|
|
166
|
+
"data-span-running",
|
|
167
|
+
);
|
|
168
|
+
expect(renderToStaticMarkup(<TimelineFixture />)).not.toContain(
|
|
169
|
+
"data-span-running",
|
|
170
|
+
);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it("passes a consumer --span-timeline-min-width through to the bar style", () => {
|
|
174
|
+
const html = renderToStaticMarkup(
|
|
175
|
+
<TimelineFixture
|
|
176
|
+
barStyle={{ "--span-timeline-min-width": "4px" } as CSSProperties}
|
|
177
|
+
/>,
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
expect(html).toContain("--span-timeline-min-width:4px");
|
|
181
|
+
expect(html).toContain("position:absolute");
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it("clamps a negative paddingEnd and leaves the default range unpadded", () => {
|
|
185
|
+
expect(renderToStaticMarkup(<TimelineFixture paddingEnd={-1} />)).toContain(
|
|
186
|
+
"--span-timeline-range-ms:100",
|
|
187
|
+
);
|
|
188
|
+
expect(renderToStaticMarkup(<TimelineFixture />)).toContain(
|
|
189
|
+
"--span-timeline-range-ms:100",
|
|
190
|
+
);
|
|
191
|
+
});
|
|
192
|
+
});
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type ComponentPropsWithoutRef,
|
|
3
|
+
type ComponentRef,
|
|
4
|
+
type CSSProperties,
|
|
5
|
+
createContext,
|
|
6
|
+
forwardRef,
|
|
7
|
+
useContext,
|
|
8
|
+
useMemo,
|
|
9
|
+
} from "react";
|
|
10
|
+
import { Primitive } from "@radix-ui/react-primitive";
|
|
11
|
+
import { useAuiState } from "@assistant-ui/store";
|
|
12
|
+
|
|
13
|
+
export type SpanTimelineRange = { min: number; max: number };
|
|
14
|
+
|
|
15
|
+
type TimelineCssProperties = CSSProperties & {
|
|
16
|
+
"--span-timeline-min-ms"?: number;
|
|
17
|
+
"--span-timeline-max-ms"?: number;
|
|
18
|
+
"--span-timeline-range-ms"?: number;
|
|
19
|
+
"--span-timeline-left"?: string;
|
|
20
|
+
"--span-timeline-end"?: string;
|
|
21
|
+
"--span-timeline-width"?: string;
|
|
22
|
+
"--span-timeline-duration-ms"?: number;
|
|
23
|
+
"--span-timeline-min-width"?: string | number;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const clampPercent = (value: number) => Math.min(100, Math.max(0, value));
|
|
27
|
+
|
|
28
|
+
const normalizeRange = (
|
|
29
|
+
range: SpanTimelineRange,
|
|
30
|
+
paddingEnd = 0,
|
|
31
|
+
): SpanTimelineRange => {
|
|
32
|
+
const duration = Math.max(1, range.max - range.min);
|
|
33
|
+
const safePaddingEnd = Math.max(0, paddingEnd);
|
|
34
|
+
return {
|
|
35
|
+
min: range.min,
|
|
36
|
+
max: range.max + duration * safePaddingEnd,
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const SpanTimelineRangeContext = createContext<SpanTimelineRange | null>(null);
|
|
41
|
+
|
|
42
|
+
export namespace SpanPrimitiveTimeline {
|
|
43
|
+
export type Element = ComponentRef<typeof Primitive.div>;
|
|
44
|
+
export type Props = ComponentPropsWithoutRef<typeof Primitive.div> & {
|
|
45
|
+
timeRange?: SpanTimelineRange | undefined;
|
|
46
|
+
paddingEnd?: number | undefined;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const SpanPrimitiveTimeline = forwardRef<
|
|
51
|
+
SpanPrimitiveTimeline.Element,
|
|
52
|
+
SpanPrimitiveTimeline.Props
|
|
53
|
+
>(({ timeRange, paddingEnd = 0, style, children, ...props }, ref) => {
|
|
54
|
+
const spanTimeRange = useAuiState((s) => s.span.timeRange);
|
|
55
|
+
const resolvedRange = useMemo(
|
|
56
|
+
() => normalizeRange(timeRange ?? spanTimeRange, paddingEnd),
|
|
57
|
+
[timeRange, spanTimeRange, paddingEnd],
|
|
58
|
+
);
|
|
59
|
+
const rangeMs = Math.max(1, resolvedRange.max - resolvedRange.min);
|
|
60
|
+
|
|
61
|
+
const mergedStyle: TimelineCssProperties = {
|
|
62
|
+
...style,
|
|
63
|
+
"--span-timeline-min-ms": resolvedRange.min,
|
|
64
|
+
"--span-timeline-max-ms": resolvedRange.max,
|
|
65
|
+
"--span-timeline-range-ms": rangeMs,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<SpanTimelineRangeContext.Provider value={resolvedRange}>
|
|
70
|
+
<Primitive.div
|
|
71
|
+
{...props}
|
|
72
|
+
ref={ref}
|
|
73
|
+
style={mergedStyle}
|
|
74
|
+
data-span-timeline=""
|
|
75
|
+
>
|
|
76
|
+
{children}
|
|
77
|
+
</Primitive.div>
|
|
78
|
+
</SpanTimelineRangeContext.Provider>
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
SpanPrimitiveTimeline.displayName = "SpanPrimitive.Timeline";
|
|
83
|
+
|
|
84
|
+
export namespace SpanPrimitiveTimelineBar {
|
|
85
|
+
export type Element = ComponentRef<typeof Primitive.div>;
|
|
86
|
+
export type Props = ComponentPropsWithoutRef<typeof Primitive.div> & {
|
|
87
|
+
now?: number | undefined;
|
|
88
|
+
timeRange?: SpanTimelineRange | undefined;
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export const getSpanTimelineBarVars = ({
|
|
93
|
+
startedAt,
|
|
94
|
+
endedAt,
|
|
95
|
+
timeRange,
|
|
96
|
+
now,
|
|
97
|
+
}: {
|
|
98
|
+
startedAt: number;
|
|
99
|
+
endedAt: number | null;
|
|
100
|
+
timeRange: SpanTimelineRange;
|
|
101
|
+
now?: number | undefined;
|
|
102
|
+
}) => {
|
|
103
|
+
const rangeMs = Math.max(1, timeRange.max - timeRange.min);
|
|
104
|
+
const effectiveEnd = endedAt ?? now ?? timeRange.max;
|
|
105
|
+
const leftPercent = clampPercent(
|
|
106
|
+
((startedAt - timeRange.min) / rangeMs) * 100,
|
|
107
|
+
);
|
|
108
|
+
const rawEndPercent = ((effectiveEnd - timeRange.min) / rangeMs) * 100;
|
|
109
|
+
const endPercent = clampPercent(Math.max(leftPercent, rawEndPercent));
|
|
110
|
+
const widthPercent = endPercent - leftPercent;
|
|
111
|
+
const durationMs = Math.max(0, effectiveEnd - startedAt);
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
leftPercent,
|
|
115
|
+
endPercent,
|
|
116
|
+
widthPercent,
|
|
117
|
+
durationMs,
|
|
118
|
+
effectiveEnd,
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export const SpanPrimitiveTimelineBar = forwardRef<
|
|
123
|
+
SpanPrimitiveTimelineBar.Element,
|
|
124
|
+
SpanPrimitiveTimelineBar.Props
|
|
125
|
+
>(({ now, timeRange, style, ...props }, ref) => {
|
|
126
|
+
const contextRange = useContext(SpanTimelineRangeContext);
|
|
127
|
+
const spanTimeRange = useAuiState((s) => s.span.timeRange);
|
|
128
|
+
const startedAt = useAuiState((s) => s.span.startedAt);
|
|
129
|
+
const endedAt = useAuiState((s) => s.span.endedAt);
|
|
130
|
+
const status = useAuiState((s) => s.span.status);
|
|
131
|
+
const type = useAuiState((s) => s.span.type);
|
|
132
|
+
|
|
133
|
+
const vars = getSpanTimelineBarVars({
|
|
134
|
+
startedAt,
|
|
135
|
+
endedAt,
|
|
136
|
+
timeRange: timeRange ?? contextRange ?? spanTimeRange,
|
|
137
|
+
now,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
const mergedStyle: TimelineCssProperties = {
|
|
141
|
+
...style,
|
|
142
|
+
position: "absolute",
|
|
143
|
+
insetInlineStart: "var(--span-timeline-left)",
|
|
144
|
+
inlineSize:
|
|
145
|
+
"max(var(--span-timeline-width), var(--span-timeline-min-width, 0px))",
|
|
146
|
+
"--span-timeline-left": `${vars.leftPercent}%`,
|
|
147
|
+
"--span-timeline-end": `${vars.endPercent}%`,
|
|
148
|
+
"--span-timeline-width": `${vars.widthPercent}%`,
|
|
149
|
+
"--span-timeline-duration-ms": vars.durationMs,
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
return (
|
|
153
|
+
<Primitive.div
|
|
154
|
+
{...props}
|
|
155
|
+
ref={ref}
|
|
156
|
+
style={mergedStyle}
|
|
157
|
+
data-span-status={status}
|
|
158
|
+
data-span-type={type}
|
|
159
|
+
data-span-running={endedAt === null ? "" : undefined}
|
|
160
|
+
/>
|
|
161
|
+
);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
SpanPrimitiveTimelineBar.displayName = "SpanPrimitive.TimelineBar";
|
package/src/primitives/span.ts
CHANGED
|
@@ -5,3 +5,8 @@ export { SpanPrimitiveStatusIndicator as StatusIndicator } from "./span/SpanStat
|
|
|
5
5
|
export { SpanPrimitiveCollapseToggle as CollapseToggle } from "./span/SpanCollapseToggle";
|
|
6
6
|
export { SpanPrimitiveIndent as Indent } from "./span/SpanIndent";
|
|
7
7
|
export { SpanPrimitiveChildren as Children } from "./span/SpanChildren";
|
|
8
|
+
export {
|
|
9
|
+
SpanPrimitiveTimeline as Timeline,
|
|
10
|
+
SpanPrimitiveTimelineBar as TimelineBar,
|
|
11
|
+
type SpanTimelineRange,
|
|
12
|
+
} from "./span/SpanTimeline";
|