@tangle-network/charts 2.0.0 → 2.0.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/README.md +3 -0
- package/dist/react/flow-waterfall.css +9 -10
- package/dist/react/index.d.ts +6 -2
- package/dist/react/index.js +150 -118
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,6 +6,8 @@ The React entry also exports `DayBars`, `HBars`, `Histogram`, `Lines`, `Meter`,
|
|
|
6
6
|
|
|
7
7
|
`FlowWaterfall` from `@tangle-network/charts/react` is the shared live trace inspector: an agent timeline (one row per agent, elbow handoffs, hatched waiting) and a virtualized span waterfall over one clock. It owns hierarchy layout, folding, search, playback, zoom, span cards and running-span growth. Producers own identity, `parentId`, explicit `status` and observed totals. Import `@tangle-network/charts/react/flow-waterfall.css`; its `fw-*` classes and six-field summary support hosts without a Tailwind build. Every color, radius and shadow in it is a Brand role (text, card, hairline, well, chart grid, status inks, the categorical tones for agents), so the host loads `@tangle-network/brand` `tokens.css` (or `legacy-light.css`) and sets its theme; the stylesheet has no color of its own. The React-free root exports the `FlowSpan` and `FlowTrace` types.
|
|
8
8
|
|
|
9
|
+
`FlowWaterfall` accepts optional `graph` and `latestEvents` React nodes. Supplying `graph` adds Graph to its existing Agents/Steps view control, including `defaultView="graph"`. The trace clock and controlled selection survive switches. Graph hides waterfall-only controls; `latestEvents` stays mounted in the header across all views.
|
|
10
|
+
|
|
9
11
|
`WaterfallHeader`, `WaterfallTimeAxis`, `WaterfallBar` and `WaterfallRow` remain available for existing consumers that own their own hierarchy and selection. All use the same `waterfallSpanGeometry` and `waterfallTicks`. Existing fixed-width cells, tones, formatting, attribution slots and unordered-time `—` marks are preserved. Optional fluid tracks, inner-bar colour/class, overlay and clipping fields support the shared inspector without changing existing calls. The primitives were extracted from Intelligence under [brand #211](https://github.com/tangle-network/brand/pull/211); the shared inspector extends that presentation ownership while leaving failure interpretation with producers.
|
|
10
12
|
|
|
11
13
|
Five figures cover the decisions a benchmark reader makes:
|
|
@@ -350,3 +352,4 @@ CHARTS_REACT_VERSION=19 CHARTS_PROOF_DIR=/tmp/charts-react19 node scripts/charts
|
|
|
350
352
|
```
|
|
351
353
|
|
|
352
354
|
Consumers: agent-record adapts record provenance; agent-app supplies application trace producers; Creative consumes both. Intelligence already uses the row/axis primitives with its controlled virtualized tree. Tangle Website’s `RecordedRunWaterfall` uses the Header/Row primitives; Blueprint Agent’s execution timeline is a separately owned follow-up. Keep these existing primitives exported. Agent-record’s earlier agent-app dependency increased its installed graph from 134 to 256 package versions (tangle-tools #1674); adopting the lower chart owner removes that framework dependency, with the actual new graph measured by the deployment owner.
|
|
355
|
+
|
|
@@ -83,11 +83,13 @@
|
|
|
83
83
|
.fw-root .fw-search-input::placeholder { color: var(--fw-muted); }
|
|
84
84
|
.fw-root .fw-search-input::-webkit-search-cancel-button { display: none; }
|
|
85
85
|
|
|
86
|
-
.fw-root .fw-summary { display:
|
|
86
|
+
.fw-root .fw-summary { display: flex; flex-wrap: wrap; align-items: center; border-bottom: 1px solid var(--fw-border); }
|
|
87
87
|
.fw-root .fw-summary > div { padding: 12px 16px; min-width: 0; }
|
|
88
|
-
.fw-root .fw-summary > div
|
|
89
|
-
.fw-root .fw-summary
|
|
90
|
-
.fw-root .fw-
|
|
88
|
+
.fw-root .fw-summary > div:nth-child(-n+2) { flex: 1; }
|
|
89
|
+
.fw-root .fw-summary > div:nth-child(n+3) { display: flex; align-items: baseline; gap: 4px; padding: 8px 6px; color: var(--fw-muted); }
|
|
90
|
+
.fw-root .fw-summary dt { font-size: 14px; line-height: 20px; color: var(--fw-muted); }
|
|
91
|
+
.fw-root .fw-value { margin-top: 4px; font-size: 28px; line-height: 34px; font-weight: 600; letter-spacing: -.02em; font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
92
|
+
.fw-root .fw-summary > div:nth-child(n+3) .fw-value { margin: 0; font-size: 14px; line-height: 20px; font-weight: 500; letter-spacing: normal; }
|
|
91
93
|
.fw-root .fw-has-errors .fw-value { color: var(--fw-failed); }
|
|
92
94
|
|
|
93
95
|
.fw-root .fw-axis { display: grid; grid-template-columns: var(--fw-label-col) minmax(0, 1fr); height: 32px; color: var(--fw-muted); font-size: 14px; }
|
|
@@ -203,7 +205,7 @@
|
|
|
203
205
|
.fw-root :is(.fw-bar, .fw-seg):hover { filter: brightness(1.18); box-shadow: inset 0 0 0 1px var(--line), 0 0 0 2px color-mix(in oklab, var(--line) 55%, transparent); z-index: 1; }
|
|
204
206
|
.fw-root .fw-bar.fw-k-tool { background: var(--dim); box-shadow: inset 0 0 0 1px var(--dim-line); }
|
|
205
207
|
.fw-root .fw-bar.fw-k-handoff { background: var(--line); height: 8px; top: calc(50% + var(--fw-bar-shift) - 4px); box-shadow: none; }
|
|
206
|
-
.fw-root .fw-bar.fw-k-waiting { background: repeating-linear-gradient(-45deg, var(--fw-hatch) 0 1px, transparent 1px 5px); box-shadow: inset 0 0 0 1px var(--fw-hatch); }
|
|
208
|
+
.fw-root .fw-bar.fw-k-waiting, .fw-root .fw-kinds .fw-swatch-wait { background: repeating-linear-gradient(-45deg, var(--fw-hatch) 0 1px, transparent 1px 5px); box-shadow: inset 0 0 0 1px var(--fw-hatch); }
|
|
207
209
|
.fw-root .fw-bar.fw-k-failed { background: color-mix(in oklab, var(--fw-failed) 22%, var(--fw-surface)); box-shadow: inset 0 0 0 1px var(--fw-failed); color: var(--fw-failed); }
|
|
208
210
|
.fw-root .fw-bar.fw-k-pipeline { background: linear-gradient(90deg, var(--fw-neutral-bar), color-mix(in oklab, var(--fw-neutral-bar) 55%, var(--fw-surface))); box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--fw-text) 12%, transparent); }
|
|
209
211
|
.fw-root .fw-bar.fw-k-pipeline.fw-has-marks { background: repeating-linear-gradient(-45deg, var(--fw-hatch) 0 1px, transparent 1px 5px); box-shadow: inset 0 0 0 1px var(--fw-hatch); }
|
|
@@ -227,7 +229,7 @@
|
|
|
227
229
|
.fw-root.fw-fill-agent .fw-kinds .fw-swatch-model { background: var(--model-fill); }
|
|
228
230
|
.fw-root.fw-fill-agent .fw-kinds .fw-swatch-tool { background: var(--tool-fill); }
|
|
229
231
|
.fw-root .fw-kinds .fw-swatch-tool { width: 12px; height: 8px; border-radius: 2px; background: var(--fw-kind-tool); }
|
|
230
|
-
.fw-root .fw-kinds .fw-swatch-wait { width: 12px; height: 8px; border-radius: 2px;
|
|
232
|
+
.fw-root .fw-kinds .fw-swatch-wait { width: 12px; height: 8px; border-radius: 2px; }
|
|
231
233
|
.fw-root .fw-kinds .fw-swatch-event { width: 8px; height: 8px; border-radius: 50%; background: var(--fw-muted); box-shadow: 0 0 0 2px var(--fw-surface); }
|
|
232
234
|
.fw-root .fw-kinds .fw-swatch-handoff { width: 10px; height: 8px; border-left: 1.5px solid var(--fw-muted); border-bottom: 1.5px solid var(--fw-muted); border-bottom-left-radius: 3px; }
|
|
233
235
|
.fw-root .fw-description { margin: 0; color: var(--fw-muted); font-size: 14px; line-height: 20px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
@@ -384,10 +386,7 @@
|
|
|
384
386
|
.fw-root .fw-card .fw-agent-dot:not([data-outcome]) { background: transparent; box-shadow: inset 0 0 0 1.5px var(--fw-muted); }
|
|
385
387
|
@container flow-waterfall (max-width: 599px) {
|
|
386
388
|
.fw-root > * { --fw-label-col: 0px; --fw-bar-shift: 8px; --fw-bar-h: 8px; --fw-row-h: 44px; }
|
|
387
|
-
.fw-root .fw-summary {
|
|
388
|
-
.fw-root .fw-summary > div { padding: 8px; }
|
|
389
|
-
.fw-root .fw-summary > div:nth-child(4) { border-left: 0; }
|
|
390
|
-
.fw-root .fw-summary > div:nth-child(n+4) { border-top: 1px solid var(--fw-border); }
|
|
389
|
+
.fw-root .fw-summary > div:nth-child(-n+2) { flex-basis: 50%; padding: 6px 8px; }
|
|
391
390
|
.fw-root :is(.fw-zoom, .fw-branch-controls, .fw-resize, .fw-links, .fw-gridlayer, .fw-marker-layer, .fw-subtitle, .fw-badge, .fw-icon-tile) { display: none; }
|
|
392
391
|
.fw-root .fw-row-state { display: inline; }
|
|
393
392
|
.fw-root .fw-key > summary { display: flex; align-items: center; min-height: 32px; cursor: pointer; }
|
package/dist/react/index.d.ts
CHANGED
|
@@ -459,7 +459,7 @@ export declare function flowWaterfallRows(trace: FlowTrace, resolutionMs?: numbe
|
|
|
459
459
|
export declare function criticalPathIds(rows: readonly FlowWaterfallRow[]): ReadonlySet<string>;
|
|
460
460
|
//#endregion
|
|
461
461
|
//#region src/react/flow-waterfall-row.d.ts
|
|
462
|
-
type FlowView = 'spans' | 'agents';
|
|
462
|
+
type FlowView = 'spans' | 'agents' | 'graph';
|
|
463
463
|
//#endregion
|
|
464
464
|
//#region src/react/flow-waterfall-time.d.ts
|
|
465
465
|
interface ViewWindow {
|
|
@@ -480,6 +480,10 @@ interface FlowWaterfallProps {
|
|
|
480
480
|
defaultCollapsed?: boolean;
|
|
481
481
|
/** `agents` shows one row per agent (the agent timeline); expanding a row opens the full span tree. */
|
|
482
482
|
defaultView?: FlowView;
|
|
483
|
+
/** Host graph rendered by the same view control, retaining the trace clock and selection. */
|
|
484
|
+
graph?: ReactNode;
|
|
485
|
+
/** Shared header feed, kept mounted across Agents, Steps and Graph. */
|
|
486
|
+
latestEvents?: ReactNode;
|
|
483
487
|
/** Host brand marks by span; the inspector draws kind glyphs without it. */
|
|
484
488
|
renderIcon?: (span: FlowSpan) => ReactNode;
|
|
485
489
|
/** Scroll height of the rows; the tree is virtualized beyond it. Defaults to 20 agent rows, or 640 px of steps. */
|
|
@@ -519,7 +523,7 @@ interface FlowWaterfallProps {
|
|
|
519
523
|
}
|
|
520
524
|
/** Shared trace inspector: the agent timeline and the span waterfall over one clock.
|
|
521
525
|
* Data remains producer-owned; playback, zoom and folding change presentation only. */
|
|
522
|
-
export declare function FlowWaterfall({ trace, live, startedAt, label, defaultCollapsed, defaultView, renderIcon, maxHeight, onSelect, markers, onTimeChange, agentFill: fillProp, selectedId, onDeselect, description, summary: showSummary, criticalPath, query: queryProp, onQueryChange, collapsed: collapsedProp, onCollapsedChange, zoom: zoomProp, onZoomChange, matchSpan }: FlowWaterfallProps): import("react").JSX.Element;
|
|
526
|
+
export declare function FlowWaterfall({ trace, live, startedAt, label, defaultCollapsed, defaultView, graph, latestEvents, renderIcon, maxHeight, onSelect, markers, onTimeChange, agentFill: fillProp, selectedId, onDeselect, description, summary: showSummary, criticalPath, query: queryProp, onQueryChange, collapsed: collapsedProp, onCollapsedChange, zoom: zoomProp, onZoomChange, matchSpan }: FlowWaterfallProps): import("react").JSX.Element;
|
|
523
527
|
//#endregion
|
|
524
528
|
//#region src/react/flow-waterfall-icons.d.ts
|
|
525
529
|
/** Kind glyphs drawn when the host supplies no `renderIcon`. Brand marks belong to the host. */
|
package/dist/react/index.js
CHANGED
|
@@ -6934,10 +6934,15 @@ function agentFamilies(agents, open) {
|
|
|
6934
6934
|
const hue = (row) => row.tone <= 0 || ++next > 5 ? 0 : 1 + [...roleOf(row.name)].reduce((hash, c) => hash * 31 + c.charCodeAt(0) >>> 0, 0) % 5;
|
|
6935
6935
|
for (const [role, members] of groups) {
|
|
6936
6936
|
if (members.length < 2) {
|
|
6937
|
-
|
|
6937
|
+
const row = members[0], tone = hue(row);
|
|
6938
|
+
out.push({
|
|
6938
6939
|
...row,
|
|
6939
|
-
tone
|
|
6940
|
-
|
|
6940
|
+
tone,
|
|
6941
|
+
own: row.own.map((mark) => ({
|
|
6942
|
+
...mark,
|
|
6943
|
+
tone
|
|
6944
|
+
}))
|
|
6945
|
+
});
|
|
6941
6946
|
continue;
|
|
6942
6947
|
}
|
|
6943
6948
|
const tone = hue(members[0]);
|
|
@@ -7960,7 +7965,8 @@ function clampWindow(view, limitMs) {
|
|
|
7960
7965
|
//#region src/react/flow-waterfall-body.tsx
|
|
7961
7966
|
const ROW_HEIGHT = {
|
|
7962
7967
|
spans: 36,
|
|
7963
|
-
agents: 40
|
|
7968
|
+
agents: 40,
|
|
7969
|
+
graph: 40
|
|
7964
7970
|
};
|
|
7965
7971
|
const OVERSCAN = 8;
|
|
7966
7972
|
/** Rows re-render once per CHUNK rows scrolled; overscan covers the rows in between. */
|
|
@@ -8690,11 +8696,13 @@ const AGENT_ROWS = 20;
|
|
|
8690
8696
|
const UNFOLD_ROWS = 12;
|
|
8691
8697
|
const END_LABEL_GUTTER = {
|
|
8692
8698
|
spans: 120,
|
|
8693
|
-
agents: 176
|
|
8699
|
+
agents: 176,
|
|
8700
|
+
graph: 176
|
|
8694
8701
|
};
|
|
8695
8702
|
const NAME_WIDTH = {
|
|
8696
8703
|
spans: 320,
|
|
8697
|
-
agents: 240
|
|
8704
|
+
agents: 240,
|
|
8705
|
+
graph: 240
|
|
8698
8706
|
};
|
|
8699
8707
|
/** State the host may own: its value wins when given, and every change is reported either way. */
|
|
8700
8708
|
function useHostable(value, onChange, initial) {
|
|
@@ -8771,7 +8779,7 @@ const TONE_ORDER = [
|
|
|
8771
8779
|
"ok"
|
|
8772
8780
|
];
|
|
8773
8781
|
/** What each mark means, as the agent view draws it; a key only for kinds the run has. */
|
|
8774
|
-
function KindLegend({ rows }) {
|
|
8782
|
+
function KindLegend({ rows, fill }) {
|
|
8775
8783
|
const has = (kind) => rows.some((row) => row.own.some((mark) => mark.kind === kind) || row.span.kind === kind);
|
|
8776
8784
|
const shown = [
|
|
8777
8785
|
["model", "Model call"],
|
|
@@ -8780,13 +8788,19 @@ function KindLegend({ rows }) {
|
|
|
8780
8788
|
["handoff", "Handoff"]
|
|
8781
8789
|
].filter(([kind]) => kind === "waiting" ? rows.some((row) => row.kind === "pipeline") : kind === "handoff" ? rows.some((row) => row.span.handoffTo || row.hasAgents) : has(kind));
|
|
8782
8790
|
if (shown.length === 0) return null;
|
|
8783
|
-
|
|
8791
|
+
const example = rows.find((row) => toneKey(row.tone) > 0 && row.own.some((mark) => mark.kind === "model")) ?? rows.find((row) => row.own.length);
|
|
8792
|
+
return /* @__PURE__ */ jsxs("ul", {
|
|
8784
8793
|
className: "fw-legend fw-kinds",
|
|
8785
8794
|
"aria-label": "Key",
|
|
8786
|
-
|
|
8795
|
+
"data-tone": fill === "agent" ? toneKey(example?.tone ?? 0) : void 0,
|
|
8796
|
+
"data-example": example?.id,
|
|
8797
|
+
children: [shown.map(([kind, name]) => /* @__PURE__ */ jsxs("li", { children: [/* @__PURE__ */ jsx("span", {
|
|
8787
8798
|
className: `fw-swatch-${kind === "waiting" ? "wait" : kind}`,
|
|
8788
8799
|
"aria-hidden": true
|
|
8789
|
-
}), name] }, kind))
|
|
8800
|
+
}), name] }, kind)), /* @__PURE__ */ jsx("li", {
|
|
8801
|
+
className: "fw-kind-rule",
|
|
8802
|
+
children: fill === "agent" ? "Bar color identifies family; shade identifies work." : "Shade identifies work."
|
|
8803
|
+
})]
|
|
8790
8804
|
});
|
|
8791
8805
|
}
|
|
8792
8806
|
/** The axis dots and the dashed lines they drop: one key naming what they mark (a release, or the kinds the host gave). */
|
|
@@ -8886,17 +8900,37 @@ function OutcomeLegend({ agents, selected, onFilter, neutral }) {
|
|
|
8886
8900
|
]
|
|
8887
8901
|
});
|
|
8888
8902
|
}
|
|
8903
|
+
function ViewControl({ view, graph, onChange }) {
|
|
8904
|
+
return /* @__PURE__ */ jsx("div", {
|
|
8905
|
+
className: "fw-views",
|
|
8906
|
+
role: "radiogroup",
|
|
8907
|
+
"aria-label": "Trace view",
|
|
8908
|
+
children: [
|
|
8909
|
+
"agents",
|
|
8910
|
+
"spans",
|
|
8911
|
+
...graph ? ["graph"] : []
|
|
8912
|
+
].map((option) => /* @__PURE__ */ jsx("button", {
|
|
8913
|
+
type: "button",
|
|
8914
|
+
role: "radio",
|
|
8915
|
+
"aria-checked": view === option,
|
|
8916
|
+
disabled: view === option,
|
|
8917
|
+
className: "fw-view-button",
|
|
8918
|
+
onClick: () => onChange(option),
|
|
8919
|
+
children: option === "agents" ? "Agents" : option === "spans" ? "Steps" : "Graph"
|
|
8920
|
+
}, option))
|
|
8921
|
+
});
|
|
8922
|
+
}
|
|
8889
8923
|
/** Shared trace inspector: the agent timeline and the span waterfall over one clock.
|
|
8890
8924
|
* Data remains producer-owned; playback, zoom and folding change presentation only. */
|
|
8891
|
-
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, criticalPath = false, query: queryProp, onQueryChange, collapsed: collapsedProp, onCollapsedChange, zoom: zoomProp, onZoomChange, matchSpan }) {
|
|
8925
|
+
function FlowWaterfall({ trace, live, startedAt, label = "Trace waterfall", defaultCollapsed = false, defaultView = "spans", graph, latestEvents, renderIcon, maxHeight, onSelect, markers, onTimeChange, agentFill: fillProp, selectedId, onDeselect, description, summary: showSummary = true, criticalPath = false, query: queryProp, onQueryChange, collapsed: collapsedProp, onCollapsedChange, zoom: zoomProp, onZoomChange, matchSpan }) {
|
|
8892
8926
|
const root = useRef(null);
|
|
8893
8927
|
const search = useRef(null);
|
|
8894
8928
|
const slider = useRef(null);
|
|
8895
8929
|
const timeOutput = useRef(null);
|
|
8896
8930
|
const hideTimer = useRef(void 0);
|
|
8897
|
-
const searchId = useId();
|
|
8898
|
-
const
|
|
8899
|
-
const
|
|
8931
|
+
const searchId = useId(), cardId = useId();
|
|
8932
|
+
const [requestedView, setView] = useState(defaultView);
|
|
8933
|
+
const view = requestedView === "graph" && graph == null ? "agents" : requestedView;
|
|
8900
8934
|
const [query, setQuery] = useHostable(queryProp, onQueryChange, "");
|
|
8901
8935
|
const [collapsed, setCollapsed] = useHostable(collapsedProp, onCollapsedChange, () => new Set(defaultCollapsed ? trace.spans.flatMap((span) => span.parentId ? [span.parentId] : []) : []));
|
|
8902
8936
|
const [speed, setSpeed] = useState(1);
|
|
@@ -9012,6 +9046,7 @@ function FlowWaterfall({ trace, live, startedAt, label = "Trace waterfall", defa
|
|
|
9012
9046
|
}, [view, agents]);
|
|
9013
9047
|
useEffect(() => {
|
|
9014
9048
|
const keydown = (event) => {
|
|
9049
|
+
if (view === "graph") return;
|
|
9015
9050
|
const active = document.activeElement;
|
|
9016
9051
|
const ownsFocus = root.current?.contains(active);
|
|
9017
9052
|
if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "f") {
|
|
@@ -9326,7 +9361,7 @@ function FlowWaterfall({ trace, live, startedAt, label = "Trace waterfall", defa
|
|
|
9326
9361
|
done && speedup >= 1.05 ? ` · ${speedup.toFixed(1)}x parallel` : ""
|
|
9327
9362
|
]
|
|
9328
9363
|
}),
|
|
9329
|
-
failedAgents > 0 && /* @__PURE__ */ jsxs("button", {
|
|
9364
|
+
view !== "graph" && failedAgents > 0 && /* @__PURE__ */ jsxs("button", {
|
|
9330
9365
|
type: "button",
|
|
9331
9366
|
className: "fw-text-button fw-alert",
|
|
9332
9367
|
"aria-pressed": filter === "__errors",
|
|
@@ -9338,7 +9373,7 @@ function FlowWaterfall({ trace, live, startedAt, label = "Trace waterfall", defa
|
|
|
9338
9373
|
" failed"
|
|
9339
9374
|
]
|
|
9340
9375
|
}),
|
|
9341
|
-
quietAgents > 0 && /* @__PURE__ */ jsxs("button", {
|
|
9376
|
+
view !== "graph" && quietAgents > 0 && /* @__PURE__ */ jsxs("button", {
|
|
9342
9377
|
type: "button",
|
|
9343
9378
|
className: "fw-text-button fw-quiet",
|
|
9344
9379
|
"aria-pressed": filter === "__quiet",
|
|
@@ -9351,7 +9386,7 @@ function FlowWaterfall({ trace, live, startedAt, label = "Trace waterfall", defa
|
|
|
9351
9386
|
children: "Live"
|
|
9352
9387
|
})
|
|
9353
9388
|
]
|
|
9354
|
-
}), /* @__PURE__ */ jsxs("details", {
|
|
9389
|
+
}), view !== "graph" && /* @__PURE__ */ jsxs("details", {
|
|
9355
9390
|
className: "fw-key",
|
|
9356
9391
|
open: root.current ? root.current.clientWidth >= 600 : true,
|
|
9357
9392
|
children: [/* @__PURE__ */ jsxs("summary", { children: ["Key", /* @__PURE__ */ jsx(ChevronGlyph, {})] }), /* @__PURE__ */ jsxs("div", {
|
|
@@ -9363,30 +9398,24 @@ function FlowWaterfall({ trace, live, startedAt, label = "Trace waterfall", defa
|
|
|
9363
9398
|
selected: filter,
|
|
9364
9399
|
onFilter: applyFilter
|
|
9365
9400
|
}),
|
|
9366
|
-
view === "agents" && /* @__PURE__ */ jsx(KindLegend, {
|
|
9401
|
+
view === "agents" && /* @__PURE__ */ jsx(KindLegend, {
|
|
9402
|
+
rows: visible,
|
|
9403
|
+
fill: agentFill
|
|
9404
|
+
}),
|
|
9367
9405
|
/* @__PURE__ */ jsx(MarkerLegend, { markers })
|
|
9368
9406
|
]
|
|
9369
9407
|
})]
|
|
9370
9408
|
})]
|
|
9371
9409
|
}), /* @__PURE__ */ jsxs("div", {
|
|
9372
9410
|
className: "fw-tools",
|
|
9373
|
-
children: [/* @__PURE__ */ jsx(
|
|
9374
|
-
|
|
9375
|
-
|
|
9376
|
-
|
|
9377
|
-
|
|
9378
|
-
|
|
9379
|
-
|
|
9380
|
-
|
|
9381
|
-
disabled: view === option,
|
|
9382
|
-
className: "fw-view-button",
|
|
9383
|
-
onClick: () => {
|
|
9384
|
-
setView(option);
|
|
9385
|
-
setNameWidth(NAME_WIDTH[option]);
|
|
9386
|
-
setCard(null);
|
|
9387
|
-
},
|
|
9388
|
-
children: option === "agents" ? "Agents" : "Steps"
|
|
9389
|
-
}, option))
|
|
9411
|
+
children: [/* @__PURE__ */ jsx(ViewControl, {
|
|
9412
|
+
view,
|
|
9413
|
+
graph: graph != null,
|
|
9414
|
+
onChange: (option) => {
|
|
9415
|
+
setView(option);
|
|
9416
|
+
setNameWidth(NAME_WIDTH[option]);
|
|
9417
|
+
setCard(null);
|
|
9418
|
+
}
|
|
9390
9419
|
}), view === "spans" && /* @__PURE__ */ jsxs("div", {
|
|
9391
9420
|
className: "fw-search",
|
|
9392
9421
|
children: [
|
|
@@ -9420,91 +9449,94 @@ function FlowWaterfall({ trace, live, startedAt, label = "Trace waterfall", defa
|
|
|
9420
9449
|
})]
|
|
9421
9450
|
})]
|
|
9422
9451
|
}),
|
|
9423
|
-
|
|
9424
|
-
|
|
9425
|
-
|
|
9426
|
-
className:
|
|
9427
|
-
children: [
|
|
9428
|
-
className: "fw-
|
|
9429
|
-
|
|
9430
|
-
|
|
9431
|
-
|
|
9432
|
-
|
|
9433
|
-
|
|
9434
|
-
|
|
9435
|
-
|
|
9436
|
-
|
|
9437
|
-
|
|
9438
|
-
|
|
9439
|
-
|
|
9440
|
-
|
|
9441
|
-
|
|
9442
|
-
|
|
9443
|
-
|
|
9444
|
-
|
|
9445
|
-
|
|
9446
|
-
|
|
9447
|
-
|
|
9448
|
-
|
|
9449
|
-
|
|
9450
|
-
|
|
9451
|
-
|
|
9452
|
-
|
|
9453
|
-
|
|
9454
|
-
|
|
9455
|
-
|
|
9456
|
-
|
|
9457
|
-
|
|
9458
|
-
|
|
9459
|
-
|
|
9460
|
-
|
|
9461
|
-
|
|
9462
|
-
|
|
9463
|
-
|
|
9464
|
-
|
|
9465
|
-
trackPx,
|
|
9466
|
-
showCursor,
|
|
9467
|
-
markers,
|
|
9468
|
-
fillByAgent: agentFill !== "outcome",
|
|
9469
|
-
zoomed: zoom !== null,
|
|
9470
|
-
renderIcon,
|
|
9471
|
-
emptyText: rows.length === 0 ? "No spans yet. Waiting for trace events." : `No matching steps for “${query}”.`,
|
|
9472
|
-
onToggle: toggle,
|
|
9473
|
-
onInspect: inspect,
|
|
9474
|
-
onLeave: leave,
|
|
9475
|
-
onPin: pin,
|
|
9476
|
-
onActivate: (row) => setActiveId(row.id),
|
|
9477
|
-
onActiveChange: setActiveId,
|
|
9478
|
-
onScrub: scrubTo,
|
|
9479
|
-
onZoom: zoomBy,
|
|
9480
|
-
onPan: pan,
|
|
9481
|
-
nameWidth,
|
|
9482
|
-
onNameWidth: (px) => {
|
|
9483
|
-
resized.current = true;
|
|
9484
|
-
setNameWidth(Math.max(140, Math.min(560, px)));
|
|
9485
|
-
},
|
|
9486
|
-
onTrack: setLaneElement,
|
|
9487
|
-
onExpandAll: rows.some((row) => row.hasChildren) ? () => setCollapsed(/* @__PURE__ */ new Set()) : void 0,
|
|
9488
|
-
onCollapseAll: () => setCollapsed(new Set(rows.filter((row) => row.hasChildren).map((row) => row.id)))
|
|
9489
|
-
}),
|
|
9490
|
-
card && cardRow && /* @__PURE__ */ jsx("div", {
|
|
9491
|
-
className: `fw-card-anchor${card.above && card.top === void 0 ? " fw-card-above" : ""}`,
|
|
9492
|
-
onPointerEnter: () => clearTimeout(hideTimer.current),
|
|
9493
|
-
onPointerLeave: card.pinned ? void 0 : leave,
|
|
9494
|
-
children: /* @__PURE__ */ jsx(SpanCard, {
|
|
9495
|
-
id: cardId,
|
|
9496
|
-
row: cardRow,
|
|
9497
|
-
agent: cardAgent,
|
|
9452
|
+
latestEvents,
|
|
9453
|
+
view === "graph" ? graph : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
9454
|
+
showSummary && /* @__PURE__ */ jsx("dl", {
|
|
9455
|
+
className: "fw-summary",
|
|
9456
|
+
children: summary.map(([name, value, title]) => /* @__PURE__ */ jsxs("div", {
|
|
9457
|
+
className: name === "Errors" && errors !== void 0 && errors > 0 ? "fw-has-errors" : void 0,
|
|
9458
|
+
children: [/* @__PURE__ */ jsx("dt", { children: name }), /* @__PURE__ */ jsx("dd", {
|
|
9459
|
+
className: "fw-value",
|
|
9460
|
+
title,
|
|
9461
|
+
children: name === "Errors" ? /* @__PURE__ */ jsx("button", {
|
|
9462
|
+
type: "button",
|
|
9463
|
+
"aria-pressed": filter === "__errors",
|
|
9464
|
+
onClick: () => applyFilter("__errors"),
|
|
9465
|
+
children: value
|
|
9466
|
+
}) : value
|
|
9467
|
+
})]
|
|
9468
|
+
}, name))
|
|
9469
|
+
}),
|
|
9470
|
+
view === "agents" && playback,
|
|
9471
|
+
/* @__PURE__ */ jsx(FlowBody, {
|
|
9472
|
+
rows: visible,
|
|
9473
|
+
byId,
|
|
9474
|
+
totalRows: rows.length,
|
|
9475
|
+
view,
|
|
9476
|
+
maxHeight: rowsHeight,
|
|
9477
|
+
collapsed,
|
|
9478
|
+
searching: Boolean(query.trim()),
|
|
9479
|
+
query,
|
|
9480
|
+
matchSpan,
|
|
9481
|
+
pauses: trace.pauses,
|
|
9482
|
+
errorTimes,
|
|
9483
|
+
cursorLine: isLive || position !== null || playing,
|
|
9484
|
+
sharedDetail,
|
|
9485
|
+
sharedOutcome,
|
|
9486
|
+
expandedIds: view === "agents" ? /* @__PURE__ */ new Set([...openFamilies, ...openSteps]) : void 0,
|
|
9487
|
+
holdHeight: isLive,
|
|
9488
|
+
slowestId: slowest?.id ?? callouts.slowestId,
|
|
9489
|
+
costliestId: callouts.costliestId,
|
|
9490
|
+
criticalIds: criticalPath && view === "spans" ? critical : void 0,
|
|
9491
|
+
activeId,
|
|
9492
|
+
selectedId: selection,
|
|
9493
|
+
focusId: cardAgent?.id ?? (view === "agents" ? activeId : void 0),
|
|
9498
9494
|
clockMs,
|
|
9499
|
-
|
|
9500
|
-
|
|
9501
|
-
|
|
9502
|
-
|
|
9495
|
+
window: win,
|
|
9496
|
+
trackPx,
|
|
9497
|
+
showCursor,
|
|
9498
|
+
markers,
|
|
9499
|
+
fillByAgent: agentFill !== "outcome",
|
|
9500
|
+
zoomed: zoom !== null,
|
|
9503
9501
|
renderIcon,
|
|
9504
|
-
|
|
9505
|
-
|
|
9506
|
-
|
|
9507
|
-
|
|
9502
|
+
emptyText: rows.length === 0 ? "No spans yet. Waiting for trace events." : `No matching steps for “${query}”.`,
|
|
9503
|
+
onToggle: toggle,
|
|
9504
|
+
onInspect: inspect,
|
|
9505
|
+
onLeave: leave,
|
|
9506
|
+
onPin: pin,
|
|
9507
|
+
onActivate: (row) => setActiveId(row.id),
|
|
9508
|
+
onActiveChange: setActiveId,
|
|
9509
|
+
onScrub: scrubTo,
|
|
9510
|
+
onZoom: zoomBy,
|
|
9511
|
+
onPan: pan,
|
|
9512
|
+
nameWidth,
|
|
9513
|
+
onNameWidth: (px) => {
|
|
9514
|
+
resized.current = true;
|
|
9515
|
+
setNameWidth(Math.max(140, Math.min(560, px)));
|
|
9516
|
+
},
|
|
9517
|
+
onTrack: setLaneElement,
|
|
9518
|
+
onExpandAll: rows.some((row) => row.hasChildren) ? () => setCollapsed(/* @__PURE__ */ new Set()) : void 0,
|
|
9519
|
+
onCollapseAll: () => setCollapsed(new Set(rows.filter((row) => row.hasChildren).map((row) => row.id)))
|
|
9520
|
+
}),
|
|
9521
|
+
card && cardRow && /* @__PURE__ */ jsx("div", {
|
|
9522
|
+
className: `fw-card-anchor${card.above && card.top === void 0 ? " fw-card-above" : ""}`,
|
|
9523
|
+
onPointerEnter: () => clearTimeout(hideTimer.current),
|
|
9524
|
+
onPointerLeave: card.pinned ? void 0 : leave,
|
|
9525
|
+
children: /* @__PURE__ */ jsx(SpanCard, {
|
|
9526
|
+
id: cardId,
|
|
9527
|
+
row: cardRow,
|
|
9528
|
+
agent: cardAgent,
|
|
9529
|
+
clockMs,
|
|
9530
|
+
left: card.left,
|
|
9531
|
+
top: card.top ?? (card.above ? card.anchorTop - 8 : card.anchorBottom + 8),
|
|
9532
|
+
pinned: card.pinned,
|
|
9533
|
+
onClose: closeCard,
|
|
9534
|
+
renderIcon,
|
|
9535
|
+
compact: view === "agents"
|
|
9536
|
+
})
|
|
9537
|
+
}),
|
|
9538
|
+
view === "spans" && playback
|
|
9539
|
+
] })
|
|
9508
9540
|
]
|
|
9509
9541
|
});
|
|
9510
9542
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/charts",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1",
|
|
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",
|