@tangle-network/charts 0.21.5 → 0.21.6
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/react/flow-waterfall.css +6 -3
- package/dist/react/index.d.ts +4 -4
- package/dist/react/index.js +17 -18
- package/package.json +1 -1
|
@@ -135,7 +135,8 @@
|
|
|
135
135
|
background: repeating-linear-gradient(-45deg, color-mix(in oklab, var(--fw-text) 9%, transparent) 0 1px, transparent 1px 6px), color-mix(in oklab, var(--fw-text) 4%, transparent);
|
|
136
136
|
border-inline: 1px dashed color-mix(in oklab, var(--fw-text) 24%, transparent); }
|
|
137
137
|
.fw-root .fw-pause-label b { font-weight: 600; color: var(--fw-text); }
|
|
138
|
-
.fw-root .fw-pause
|
|
138
|
+
.fw-root .fw-pause { overflow: visible; }
|
|
139
|
+
.fw-root .fw-pause-label { position: sticky; top: 4px; display: block; width: max-content; margin: 4px 0 0 50%; translate: -50% 0; padding: 0 8px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
139
140
|
border-radius: 4px; font-size: 12px; line-height: 20px; color: var(--fw-muted); background: var(--fw-surface); box-shadow: inset 0 0 0 1px var(--fw-border); }
|
|
140
141
|
/* The label alone takes the pointer, for its reason; the band stays click-through to the rows. */
|
|
141
142
|
.fw-root .fw-pause-label[title] { pointer-events: auto; cursor: help; }
|
|
@@ -265,7 +266,6 @@
|
|
|
265
266
|
.fw-root .fw-seg-failed { background: color-mix(in oklab, var(--fw-failed) 18%, var(--fw-surface)); box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--fw-failed) 70%, transparent); color: var(--fw-failed); }
|
|
266
267
|
/* In the agent view a failed turn draws like any turn; the agent's own failure shows once, by its name and its end label. */
|
|
267
268
|
.fw-root .fw-view-agents .fw-seg-failed { background: var(--dim); box-shadow: inset 0 0 0 1px var(--dim-line); }
|
|
268
|
-
.fw-root .fw-view-agents .fw-alert { color: var(--fw-muted); }
|
|
269
269
|
.fw-root .fw-glyph { display: inline-flex; color: currentColor; }
|
|
270
270
|
.fw-root .fw-glyph svg { width: 11px; height: 11px; stroke-width: 2; }
|
|
271
271
|
.fw-root .fw-seg-model .fw-glyph, .fw-root .fw-k-model .fw-glyph { color: light-dark(var(--tone), #fff); }
|
|
@@ -304,7 +304,10 @@
|
|
|
304
304
|
.fw-root.fw-root-agents .fw-card, .fw-root.fw-root-agents .fw-card-above .fw-card { position: relative; left: auto !important; top: auto !important; transform: none; animation-name: fw-arrive; width: auto; max-width: 560px; }
|
|
305
305
|
.fw-root .fw-seg-alt { filter: brightness(.78); }
|
|
306
306
|
/* Agent view: the scrubber track shows how far the run has played, so at rest it reads full, not empty. */
|
|
307
|
-
.fw-root-agents .fw-slider { background: linear-gradient(90deg,
|
|
307
|
+
.fw-root.fw-root-agents .fw-slider { background: linear-gradient(90deg, var(--fw-accent) var(--fw-progress), var(--fw-well) var(--fw-progress)) 0 50% / 100% 6px no-repeat; }
|
|
308
|
+
/* The playhead: a round knob on a filled track, visible at rest as the references show it. */
|
|
309
|
+
.fw-root.fw-root-agents .fw-slider::-webkit-slider-thumb { width: 14px; height: 14px; border-radius: 50%; background: var(--fw-text); box-shadow: 0 0 0 3px var(--fw-surface); }
|
|
310
|
+
.fw-root.fw-root-agents .fw-slider::-moz-range-thumb { width: 14px; height: 14px; border-radius: 50%; background: var(--fw-text); box-shadow: 0 0 0 3px var(--fw-surface); }
|
|
308
311
|
.fw-root .fw-card { position: absolute; z-index: 20; width: 320px; padding: 12px; border-radius: 12px; background: var(--fw-raised); border: 1px solid var(--fw-border);
|
|
309
312
|
box-shadow: 0 12px 32px -8px rgb(0 0 0 / .28), 0 2px 6px rgb(0 0 0 / .08); animation: fw-arrive 140ms var(--fw-ease); }
|
|
310
313
|
/* A hover card never covers the next mark: only a pinned card (a dialog) takes the pointer. */
|
package/dist/react/index.d.ts
CHANGED
|
@@ -399,9 +399,9 @@ interface FlowWaterfallProps {
|
|
|
399
399
|
markers?: FlowMarker[];
|
|
400
400
|
/** The time the reader moved to, in trace ms; `null` when following live or showing the whole trace. */
|
|
401
401
|
onTimeChange?: (t: number | null) => void;
|
|
402
|
-
/** What an agent bar's color means. `
|
|
403
|
-
*
|
|
404
|
-
* bar takes its outcome's color. */
|
|
402
|
+
/** What an agent bar's color means. Default: `outcome` when any agent carries one, so bars match the outcome legend, else `muted`.
|
|
403
|
+
* `muted`: every agent one quiet tone, color spent on state only (red for failure, amber for the slowest). `agent`: each agent its
|
|
404
|
+
* own hue, shared by its steps and handoffs. `outcome`: the bar takes its outcome's color. */
|
|
405
405
|
agentFill?: 'muted' | 'outcome' | 'agent';
|
|
406
406
|
/** One line beside the title saying what the run was for, such as its goal. */
|
|
407
407
|
description?: string;
|
|
@@ -415,6 +415,6 @@ interface FlowWaterfallProps {
|
|
|
415
415
|
}
|
|
416
416
|
/** Shared trace inspector: the agent timeline and the span waterfall over one clock.
|
|
417
417
|
* Data remains producer-owned; playback, zoom and folding change presentation only. */
|
|
418
|
-
export declare function FlowWaterfall({ trace, live, startedAt, label, defaultCollapsed, defaultView, renderIcon, maxHeight, onSelect, markers, onTimeChange, agentFill, selectedId, onDeselect, description, summary: showSummary }: FlowWaterfallProps): import("react").JSX.Element;
|
|
418
|
+
export declare function FlowWaterfall({ trace, live, startedAt, label, defaultCollapsed, defaultView, renderIcon, maxHeight, onSelect, markers, onTimeChange, agentFill: fillProp, selectedId, onDeselect, description, summary: showSummary }: FlowWaterfallProps): import("react").JSX.Element;
|
|
419
419
|
//#endregion
|
|
420
420
|
export type { BandKind, ChartBand, ChartMark, DotMapLabel, DotMapProps, DotMapRect, Figure, FigureAtWidth, FigureViewProps, FlowWaterfallProps, GapBand, GapProps, LineSeries, MarkKind, MarkVerdict, MarkerShape, MeterSegment, PointFields, PointGlyph, Refusal, SparklineDirection, SparklineGeometry, SparklineGeometryOptions, SparklineLabelOptions, SparklinePoint, SparklineProps, SparklineValues, StackedBarBucket, StackedBarChartProps, StackedBarSegment, StackedBarSeries, TickOutcome, TimelineLane, TimelineOptions, TimelineSpan, TimelineTick, TimelineViewProps, WaterfallBarProps, WaterfallHeaderProps, WaterfallRowProps, WaterfallSpanGeometry, WaterfallTimeAxisProps, WaterfallWindow, XCategory, YScale, YTarget, YTick };
|
package/dist/react/index.js
CHANGED
|
@@ -2631,8 +2631,8 @@ function slowestRow(rows, clockMs) {
|
|
|
2631
2631
|
function agentCallouts(agents, clockMs) {
|
|
2632
2632
|
let slowest, slowestMs = -1, costliest, top = -1, priced = 0, timed = 0;
|
|
2633
2633
|
for (const row of agents) {
|
|
2634
|
-
if (row.durationLabel === "—" || row.span.startMs > clockMs) continue;
|
|
2635
|
-
if (row.
|
|
2634
|
+
if (row.durationLabel === "—" || row.span.startMs > clockMs || row.kind !== "pipeline" || row.id.startsWith("family:") || row.id.startsWith("run:")) continue;
|
|
2635
|
+
if (row.parentId !== void 0) {
|
|
2636
2636
|
const ms = (spanRunning(row.span) ? Math.max(row.span.endMs, clockMs) : Math.min(row.span.endMs, clockMs)) - row.span.startMs;
|
|
2637
2637
|
timed += 1;
|
|
2638
2638
|
if (ms > slowestMs) {
|
|
@@ -3442,7 +3442,7 @@ const FlowRow = memo(function FlowRow(props) {
|
|
|
3442
3442
|
"aria-label": `${row.descendants} hidden steps`,
|
|
3443
3443
|
children: ["+", row.descendants]
|
|
3444
3444
|
}),
|
|
3445
|
-
!row.ok && /* @__PURE__ */ jsx("span", {
|
|
3445
|
+
!row.ok && !agentView && /* @__PURE__ */ jsx("span", {
|
|
3446
3446
|
className: "fw-alert",
|
|
3447
3447
|
children: /* @__PURE__ */ jsx(AlertGlyph, { label: "failed" })
|
|
3448
3448
|
})
|
|
@@ -3733,6 +3733,7 @@ function FlowBody(props) {
|
|
|
3733
3733
|
const ticks = clockTicks(win.startMs, tickEnd, Math.max(1, trackPx + (view === "spans" ? 72 : 0)));
|
|
3734
3734
|
const markerLabels = useMemo(() => {
|
|
3735
3735
|
const shown = /* @__PURE__ */ new Map();
|
|
3736
|
+
if (view === "agents") return shown;
|
|
3736
3737
|
let freeFrom = -Infinity;
|
|
3737
3738
|
for (const marker of [...props.markers ?? []].sort((a, b) => a.at - b.at)) {
|
|
3738
3739
|
const x = (marker.at - win.startMs) / msPerPx;
|
|
@@ -3748,7 +3749,8 @@ function FlowBody(props) {
|
|
|
3748
3749
|
props.markers,
|
|
3749
3750
|
win.startMs,
|
|
3750
3751
|
msPerPx,
|
|
3751
|
-
trackPx
|
|
3752
|
+
trackPx,
|
|
3753
|
+
view
|
|
3752
3754
|
]);
|
|
3753
3755
|
useEffect(() => {
|
|
3754
3756
|
const element = scroller.current;
|
|
@@ -4027,16 +4029,12 @@ function FlowBody(props) {
|
|
|
4027
4029
|
"--e": pause.endMs
|
|
4028
4030
|
},
|
|
4029
4031
|
title: pause.label,
|
|
4030
|
-
children: /* @__PURE__ */
|
|
4032
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
4031
4033
|
className: "fw-pause-label",
|
|
4032
|
-
title: pause.detail,
|
|
4033
|
-
tabIndex:
|
|
4034
|
-
"aria-label": pause.
|
|
4035
|
-
children:
|
|
4036
|
-
/* @__PURE__ */ jsx("b", { children: duration(pause.endMs - pause.startMs) }),
|
|
4037
|
-
" ",
|
|
4038
|
-
pause.label
|
|
4039
|
-
]
|
|
4034
|
+
title: pause.detail ? `${pause.label}: ${pause.detail}` : pause.label,
|
|
4035
|
+
tabIndex: 0,
|
|
4036
|
+
"aria-label": `${pause.label}, ${duration(pause.endMs - pause.startMs)}${pause.detail ? `: ${pause.detail}` : ""}`,
|
|
4037
|
+
children: /* @__PURE__ */ jsx("b", { children: duration(pause.endMs - pause.startMs) })
|
|
4040
4038
|
})
|
|
4041
4039
|
}, `p-${pause.startMs}`)), props.markers?.map((marker) => /* @__PURE__ */ jsx("span", {
|
|
4042
4040
|
className: "fw-marker",
|
|
@@ -4318,6 +4316,7 @@ function PlaybackBar({ view, playing, limit, clockMs, speed, zoom, marks, slider
|
|
|
4318
4316
|
//#region src/react/flow-waterfall.tsx
|
|
4319
4317
|
const LANE_PAD = 12;
|
|
4320
4318
|
const AGENT_ROWS = 20;
|
|
4319
|
+
const UNFOLD_ROWS = 12;
|
|
4321
4320
|
const END_LABEL_GUTTER = {
|
|
4322
4321
|
spans: 120,
|
|
4323
4322
|
agents: 176
|
|
@@ -4428,7 +4427,7 @@ function OutcomeLegend({ agents }) {
|
|
|
4428
4427
|
}
|
|
4429
4428
|
/** Shared trace inspector: the agent timeline and the span waterfall over one clock.
|
|
4430
4429
|
* Data remains producer-owned; playback, zoom and folding change presentation only. */
|
|
4431
|
-
function FlowWaterfall({ trace, live, startedAt, label = "Trace waterfall", defaultCollapsed = false, defaultView = "spans", renderIcon, maxHeight, onSelect, markers, onTimeChange, agentFill
|
|
4430
|
+
function FlowWaterfall({ trace, live, startedAt, label = "Trace waterfall", defaultCollapsed = false, defaultView = "spans", renderIcon, maxHeight, onSelect, markers, onTimeChange, agentFill: fillProp, selectedId, onDeselect, description, summary: showSummary = true }) {
|
|
4432
4431
|
const root = useRef(null);
|
|
4433
4432
|
const search = useRef(null);
|
|
4434
4433
|
const slider = useRef(null);
|
|
@@ -4450,6 +4449,7 @@ function FlowWaterfall({ trace, live, startedAt, label = "Trace waterfall", defa
|
|
|
4450
4449
|
const [laneElement, setLaneElement] = useState(null);
|
|
4451
4450
|
const observedTotal = Number.isFinite(trace.totalMs) && trace.totalMs >= 0 ? trace.totalMs : 0;
|
|
4452
4451
|
const isLive = live ?? trace.spans.some(spanRunning);
|
|
4452
|
+
const agentFill = fillProp ?? (trace.spans.some((span) => span.kind === "pipeline" && span.outcome) ? "outcome" : "muted");
|
|
4453
4453
|
const dataEnd = useMemo(() => Math.max(observedTotal, ...trace.spans.map((span) => Number.isFinite(span.endMs) ? span.endMs : 0)), [trace, observedTotal]);
|
|
4454
4454
|
const trackPx = Math.max(40, laneWidth - LANE_PAD - Math.min(END_LABEL_GUTTER[view], laneWidth * .3));
|
|
4455
4455
|
useEffect(() => {
|
|
@@ -4503,7 +4503,7 @@ function FlowWaterfall({ trace, live, startedAt, label = "Trace waterfall", defa
|
|
|
4503
4503
|
}, [rows]);
|
|
4504
4504
|
const sharedDetail = agents.length > 1 && agents.every((row) => row.span.detail && row.span.detail === agents[0]?.span.detail) ? agents[0]?.span.detail : void 0;
|
|
4505
4505
|
const [flippedFamilies, setFlippedFamilies] = useState(/* @__PURE__ */ new Set());
|
|
4506
|
-
const openFamilies = useMemo(() => defaultOpenFamilies(agents,
|
|
4506
|
+
const openFamilies = useMemo(() => defaultOpenFamilies(agents, UNFOLD_ROWS, flippedFamilies), [agents, flippedFamilies]);
|
|
4507
4507
|
const [openSteps, setOpenSteps] = useState(/* @__PURE__ */ new Set());
|
|
4508
4508
|
const visible = useMemo(() => view === "agents" ? agentViewRows(agents, rows, openFamilies, openSteps) : visibleFlowWaterfallRows(rows, query, collapsed), [
|
|
4509
4509
|
view,
|
|
@@ -4718,8 +4718,7 @@ function FlowWaterfall({ trace, live, startedAt, label = "Trace waterfall", defa
|
|
|
4718
4718
|
const cardAgent = cardRow && (() => {
|
|
4719
4719
|
for (let cursor = cardRow; cursor; cursor = cursor.parentId ? byId.get(cursor.parentId) : void 0) if (cursor.kind === "pipeline") return shown(cursor);
|
|
4720
4720
|
})();
|
|
4721
|
-
const
|
|
4722
|
-
const showCursor = moving || view === "agents";
|
|
4721
|
+
const showCursor = isLive || position !== null || playing || view === "agents";
|
|
4723
4722
|
const overviewMarks = useMemo(() => rows.filter((row) => !row.parentId).flatMap((row) => row.hasChildren ? row.segments : row.kind === "pipeline" ? [] : [{
|
|
4724
4723
|
startMs: row.span.startMs,
|
|
4725
4724
|
endMs: row.span.endMs,
|
|
@@ -4886,7 +4885,7 @@ function FlowWaterfall({ trace, live, startedAt, label = "Trace waterfall", defa
|
|
|
4886
4885
|
collapsed,
|
|
4887
4886
|
searching: Boolean(query.trim()),
|
|
4888
4887
|
pauses: trace.pauses,
|
|
4889
|
-
cursorLine:
|
|
4888
|
+
cursorLine: position !== null || playing,
|
|
4890
4889
|
sharedDetail,
|
|
4891
4890
|
expandedIds: view === "agents" ? /* @__PURE__ */ new Set([...openFamilies, ...openSteps]) : void 0,
|
|
4892
4891
|
holdHeight: isLive,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/charts",
|
|
3
|
-
"version": "0.21.
|
|
3
|
+
"version": "0.21.6",
|
|
4
4
|
"description": "Static SVG and HTML figures for benchmarks and operational timing. Draws from producer data and refuses what it cannot draw honestly.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|