@oh-my-pi/omp-stats 18.7.0 → 18.8.1
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/CHANGELOG.md +7 -0
- package/dist/client/index.css +1 -1
- package/dist/client/index.js +96 -96
- package/dist/types/aggregator.d.ts +3 -0
- package/dist/types/client/api.d.ts +5 -1
- package/dist/types/client/data/live.d.ts +16 -11
- package/dist/types/client/data/query-store.d.ts +39 -0
- package/dist/types/client/data/query.d.ts +10 -5
- package/dist/types/client/traces/Minimap.d.ts +2 -0
- package/dist/types/client/traces/TimelineCanvas.d.ts +29 -8
- package/dist/types/client/traces/TranscriptList.d.ts +3 -1
- package/dist/types/db.d.ts +14 -2
- package/dist/types/embedded-client.d.ts +5 -0
- package/dist/types/live.d.ts +5 -3
- package/dist/types/rollup.d.ts +9 -1
- package/dist/types/trace.d.ts +18 -6
- package/package.json +4 -4
- package/src/aggregator.ts +26 -9
- package/src/client/api.ts +40 -5
- package/src/client/app/LiveChip.tsx +2 -2
- package/src/client/app/Shell.tsx +2 -2
- package/src/client/data/live.tsx +85 -45
- package/src/client/data/query-store.ts +108 -0
- package/src/client/data/query.ts +47 -56
- package/src/client/routes/CostsRoute.tsx +4 -2
- package/src/client/routes/ErrorsRoute.tsx +3 -1
- package/src/client/routes/FrustrationRoute.tsx +1 -1
- package/src/client/routes/GainRoute.tsx +3 -1
- package/src/client/routes/ModelsRoute.tsx +9 -2
- package/src/client/routes/OverviewRoute.tsx +2 -2
- package/src/client/routes/ProjectsRoute.tsx +1 -1
- package/src/client/routes/ProvidersRoute.tsx +5 -3
- package/src/client/routes/RequestsRoute.tsx +1 -1
- package/src/client/routes/ToolsRoute.tsx +1 -1
- package/src/client/routes/TracesRoute.tsx +5 -4
- package/src/client/traces/Minimap.tsx +63 -26
- package/src/client/traces/TimelineCanvas.tsx +224 -105
- package/src/client/traces/TraceView.tsx +29 -10
- package/src/client/traces/TranscriptList.tsx +17 -9
- package/src/client/traces/traces.css +26 -0
- package/src/client/ui/RequestDrawer.tsx +3 -1
- package/src/db.ts +106 -64
- package/src/embedded-client.ts +9 -0
- package/src/live.ts +36 -11
- package/src/parser.ts +1 -8
- package/src/rollup.ts +41 -20
- package/src/server.ts +38 -24
- package/src/trace.ts +54 -40
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Timeline overview strip: per-category density over the full virtual domain
|
|
3
3
|
* plus a draggable/resizable viewport brush, mirroring DevTools' overview.
|
|
4
|
+
* The density layer is painted once per trace/scale/size/theme into an
|
|
5
|
+
* offscreen canvas; pan and zoom only blit it and redraw the brush.
|
|
4
6
|
*/
|
|
5
7
|
|
|
6
|
-
import { useCallback, useEffect, useRef, useState } from "react";
|
|
8
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
7
9
|
import type { TraceSpanKind, TraceTrack } from "../types";
|
|
8
10
|
import type { TimelineViewport } from "./TimelineCanvas";
|
|
9
11
|
import type { TraceScale } from "./time-scale";
|
|
10
|
-
import { useTraceTheme } from "./trace-colors";
|
|
12
|
+
import { type TraceTheme, useTraceTheme } from "./trace-colors";
|
|
11
13
|
|
|
12
14
|
export interface MinimapProps {
|
|
13
15
|
tracks: TraceTrack[];
|
|
@@ -23,6 +25,59 @@ const MIN_WINDOW_U = 10;
|
|
|
23
25
|
|
|
24
26
|
type DragMode = "move" | "left" | "right" | "create";
|
|
25
27
|
|
|
28
|
+
/** Paint the density strips (bucketed span coverage per pixel per category) at device resolution. */
|
|
29
|
+
function paintDensity(
|
|
30
|
+
tracks: TraceTrack[],
|
|
31
|
+
scale: TraceScale,
|
|
32
|
+
width: number,
|
|
33
|
+
colors: TraceTheme,
|
|
34
|
+
): OffscreenCanvas | HTMLCanvasElement {
|
|
35
|
+
const dpr = devicePixelRatio;
|
|
36
|
+
const pixelWidth = Math.floor(width * dpr);
|
|
37
|
+
const pixelHeight = Math.floor(HEIGHT * dpr);
|
|
38
|
+
let layer: OffscreenCanvas | HTMLCanvasElement;
|
|
39
|
+
let ctx: OffscreenCanvasRenderingContext2D | CanvasRenderingContext2D | null;
|
|
40
|
+
if (typeof OffscreenCanvas === "undefined") {
|
|
41
|
+
const canvas = document.createElement("canvas");
|
|
42
|
+
canvas.width = pixelWidth;
|
|
43
|
+
canvas.height = pixelHeight;
|
|
44
|
+
layer = canvas;
|
|
45
|
+
ctx = canvas.getContext("2d");
|
|
46
|
+
} else {
|
|
47
|
+
const canvas = new OffscreenCanvas(pixelWidth, pixelHeight);
|
|
48
|
+
layer = canvas;
|
|
49
|
+
ctx = canvas.getContext("2d");
|
|
50
|
+
}
|
|
51
|
+
if (!ctx) return layer;
|
|
52
|
+
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
53
|
+
|
|
54
|
+
const [d0, d1] = scale.domain;
|
|
55
|
+
const dSpan = Math.max(d1 - d0, 1e-9);
|
|
56
|
+
const buckets = STRIP_KINDS.map(() => new Float32Array(width));
|
|
57
|
+
for (const track of tracks) {
|
|
58
|
+
for (const span of track.spans) {
|
|
59
|
+
const k = STRIP_KINDS.indexOf(span.kind);
|
|
60
|
+
if (k === -1) continue;
|
|
61
|
+
const strip = buckets[k];
|
|
62
|
+
const x0 = Math.max(0, Math.floor(((scale.toU(span.start) - d0) / dSpan) * width));
|
|
63
|
+
const x1 = Math.min(width - 1, Math.ceil(((scale.toU(span.end) - d0) / dSpan) * width));
|
|
64
|
+
for (let x = x0; x <= x1; x++) strip[x] = Math.min(1, strip[x] + 0.34);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const stripH = HEIGHT / STRIP_KINDS.length;
|
|
68
|
+
for (let k = 0; k < STRIP_KINDS.length; k++) {
|
|
69
|
+
const strip = buckets[k];
|
|
70
|
+
ctx.fillStyle = colors.category[STRIP_KINDS[k]];
|
|
71
|
+
for (let x = 0; x < width; x++) {
|
|
72
|
+
if (strip[x] <= 0) continue;
|
|
73
|
+
ctx.globalAlpha = 0.25 + strip[x] * 0.75;
|
|
74
|
+
ctx.fillRect(x, k * stripH + 1, 1, stripH - 2);
|
|
75
|
+
}
|
|
76
|
+
ctx.globalAlpha = 1;
|
|
77
|
+
}
|
|
78
|
+
return layer;
|
|
79
|
+
}
|
|
80
|
+
|
|
26
81
|
export function Minimap({ tracks, scale, viewport, onViewportChange }: MinimapProps) {
|
|
27
82
|
const colors = useTraceTheme();
|
|
28
83
|
const canvasRef = useRef<HTMLCanvasElement>(null);
|
|
@@ -44,36 +99,18 @@ export function Minimap({ tracks, scale, viewport, onViewportChange }: MinimapPr
|
|
|
44
99
|
const toX = useCallback((u: number) => ((u - d0) / dSpan) * width, [d0, dSpan, width]);
|
|
45
100
|
const toU = useCallback((x: number) => d0 + (x / Math.max(width, 1)) * dSpan, [d0, dSpan, width]);
|
|
46
101
|
|
|
102
|
+
const density = useMemo(() => paintDensity(tracks, scale, width, colors), [tracks, scale, width, colors]);
|
|
103
|
+
|
|
47
104
|
useEffect(() => {
|
|
48
105
|
const canvas = canvasRef.current;
|
|
49
106
|
if (!canvas) return;
|
|
50
107
|
const ctx = canvas.getContext("2d");
|
|
51
108
|
if (!ctx) return;
|
|
52
109
|
const dpr = devicePixelRatio;
|
|
110
|
+
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
111
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
112
|
+
ctx.drawImage(density, 0, 0);
|
|
53
113
|
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
54
|
-
ctx.clearRect(0, 0, width, HEIGHT);
|
|
55
|
-
|
|
56
|
-
// Density strips: bucket span coverage per pixel per category.
|
|
57
|
-
const stripH = HEIGHT / STRIP_KINDS.length;
|
|
58
|
-
for (let k = 0; k < STRIP_KINDS.length; k++) {
|
|
59
|
-
const kind = STRIP_KINDS[k];
|
|
60
|
-
const buckets = new Float32Array(width);
|
|
61
|
-
for (const track of tracks) {
|
|
62
|
-
for (const span of track.spans) {
|
|
63
|
-
if (span.kind !== kind) continue;
|
|
64
|
-
const x0 = Math.max(0, Math.floor(toX(scale.toU(span.start))));
|
|
65
|
-
const x1 = Math.min(width - 1, Math.ceil(toX(scale.toU(span.end))));
|
|
66
|
-
for (let x = x0; x <= x1; x++) buckets[x] = Math.min(1, buckets[x] + 0.34);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
ctx.fillStyle = colors.category[kind];
|
|
70
|
-
for (let x = 0; x < width; x++) {
|
|
71
|
-
if (buckets[x] <= 0) continue;
|
|
72
|
-
ctx.globalAlpha = 0.25 + buckets[x] * 0.75;
|
|
73
|
-
ctx.fillRect(x, k * stripH + 1, 1, stripH - 2);
|
|
74
|
-
}
|
|
75
|
-
ctx.globalAlpha = 1;
|
|
76
|
-
}
|
|
77
114
|
|
|
78
115
|
// Viewport brush.
|
|
79
116
|
const vx0 = toX(viewport.u0);
|
|
@@ -85,7 +122,7 @@ export function Minimap({ tracks, scale, viewport, onViewportChange }: MinimapPr
|
|
|
85
122
|
ctx.fillStyle = colors.selection;
|
|
86
123
|
ctx.fillRect(vx0, 0, 2, HEIGHT);
|
|
87
124
|
ctx.fillRect(vx1 - 2, 0, 2, HEIGHT);
|
|
88
|
-
}, [
|
|
125
|
+
}, [density, viewport, colors, toX]);
|
|
89
126
|
|
|
90
127
|
const handlePointerDown = (event: React.PointerEvent<HTMLCanvasElement>) => {
|
|
91
128
|
const rect = event.currentTarget.getBoundingClientRect();
|