← All @molecule/* packages · App templates
@molecule/app-trace-waterfall-reactFeature · trace-waterfall · App (browser) · v1.0.1 · Apache-2.0
Distributed-trace span waterfall view (Datadog/Jaeger-style).
npm install @molecule/app-trace-waterfall-react@molecule/app-trace-waterfall-react is a ready-made trace-waterfall feature for the app (browser) side. It composes the core interfaces it needs, so it works with whichever providers your app has bonded.
import { TraceWaterfall } from '@molecule/app-trace-waterfall-react'
;<TraceWaterfall
spans={[
{
id: 'root',
name: 'GET /checkout',
service: 'api-gw',
startTime: 0,
duration: 320,
status: 'ok',
},
{
id: 'auth',
parentId: 'root',
name: 'verifyToken',
service: 'auth-svc',
startTime: 5,
duration: 40,
status: 'ok',
},
{
id: 'db',
parentId: 'root',
name: 'db.query',
service: 'postgres',
startTime: 50,
duration: 210,
status: 'ok',
},
{
id: 'cache',
parentId: 'root',
name: 'cache.get',
service: 'redis',
startTime: 45,
duration: 8,
status: 'error',
},
]}
onSpanClick={(span) => console.log('selected', span.id)}
emptyState={<p>No trace data.</p>}
/>Works with: @molecule/app-react, @molecule/app-ui, @molecule/app-ui-react
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
Distributed-trace span waterfall visualization.
Exports <TraceWaterfall>, the Span / SpanStatus / SpanRow /
SpanLayout types, and the pure layoutSpans() / serviceColor() /
formatDurationLabel() helpers used to position rows.
import { TraceWaterfall } from '@molecule/app-trace-waterfall-react'
;<TraceWaterfall
spans={[
{
id: 'root',
name: 'GET /checkout',
service: 'api-gw',
startTime: 0,
duration: 320,
status: 'ok',
},
{
id: 'auth',
parentId: 'root',
name: 'verifyToken',
service: 'auth-svc',
startTime: 5,
duration: 40,
status: 'ok',
},
{
id: 'db',
parentId: 'root',
name: 'db.query',
service: 'postgres',
startTime: 50,
duration: 210,
status: 'ok',
},
{
id: 'cache',
parentId: 'root',
name: 'cache.get',
service: 'redis',
startTime: 45,
duration: 8,
status: 'error',
},
]}
onSpanClick={(span) => console.log('selected', span.id)}
emptyState={<p>No trace data.</p>}
/>
feature
npm install @molecule/app-trace-waterfall-react @molecule/app-react @molecule/app-ui @molecule/app-ui-react react
npm install -D @types/react
SpanA single distributed-trace span. Times are numeric milliseconds (labels
assume ms; layout is unit-agnostic) — startTime and duration must
share a unit. The tree is formed by parentId references; spans without
a parentId (or whose parentId isn't present in the input array) are
roots.
interface Span {
/** Stable id for this span. */
id: string
/** Id of the parent span; omit (or set undefined) for a root span. */
parentId?: string
/** Operation name (e.g. `GET /users/:id`, `db.query`). */
name: string
/** Service / component label that emitted this span (e.g. `auth-api`). */
service?: string
/**
* Start time relative to some shared origin. Any unit is fine as long as
* it matches `duration`; the trace is auto-scaled to its own min/max.
*/
startTime: number
/** Duration in the same unit as `startTime`. Must be >= 0. */
duration: number
/** Optional status; controls the bar color. */
status?: SpanStatus
/** Optional structured attributes (tags, key/value pairs). */
attributes?: Record<string, unknown>
}
SpanLayoutOutput of layoutSpans: ordered rows + the trace's absolute time bounds.
interface SpanLayout {
/** Rows in render order (depth-first, sorted by `startTime`). */
rows: SpanRow[]
/** Earliest `startTime` across all spans (the trace origin on the axis). */
traceStart: number
/** Latest end time (`startTime + duration`) across all spans. */
traceEnd: number
/** `traceEnd - traceStart`, clamped to a minimum of `1` to avoid divide-by-zero. */
traceDuration: number
}
SpanRowLayout metadata computed for a single span row.
interface SpanRow {
/** The original span. */
span: Span
/** Zero-based depth in the parent tree (root === 0). */
depth: number
/** Position of the bar's left edge as a fraction `[0, 1]` of the trace duration. */
startFraction: number
/** Width of the bar as a fraction `[0, 1]` of the trace duration. */
widthFraction: number
}
TraceWaterfallPropsPublic props for <TraceWaterfall>.
interface TraceWaterfallProps {
/** Flat list of spans; tree is derived from `parentId` references. */
spans: Span[]
/** Optional root span id to focus the view on a single subtree. */
rootSpanId?: string
/** Click handler invoked when a span row (label or bar) is selected. */
onSpanClick?: (span: Span) => void
/** Optional content shown when `spans` is empty. */
emptyState?: React.ReactNode
/** Extra classes merged onto the root via `cm.cn`. */
className?: string
}
SpanStatusStatus indicator for a span. Mirrors common OTel-style status semantics.
type SpanStatus = 'ok' | 'error' | 'pending'
formatDurationLabel(value)Format a duration value (in the same unit as Span.startTime) as a
short, human-readable string: < 1 → microseconds, < 1000 → ms,
otherwise seconds with one decimal.
function formatDurationLabel(value: number): string
value — The numeric value to format.Returns: A short label string.
layoutSpans(spans, rootSpanId)Build a hierarchical, time-positioned layout for a flat list of spans.
Behavior:
parentId. A span whose parentId is missing from
the input (or undefined) is treated as a root.rootSpanId is provided AND that id exists in the input, the
layout is restricted to that span and its descendants. Otherwise every
root contributes its own subtree.startTime ascending (stable for equal times).traceStart / traceEnd are derived from the included spans only.traceDuration is clamped to >= 1 so callers can safely divide.The output is intentionally framework-agnostic: callers (such as
<TraceWaterfall>) can render the rows however they like.
function layoutSpans(spans: Span[], rootSpanId?: string): SpanLayout
spans — Flat list of spans, in any order.rootSpanId — Optional id to use as the visible root.Returns: Layout rows, sorted depth-first, with normalized fractions.
serviceColor(service)Deterministically derive a hex color from a service name. Used for the color tag next to each span row. Same input always yields the same color across renders so a service is visually stable.
function serviceColor(service: string): string
service — Service / component label.Returns: A hex color string suitable for an inline style.background.
TraceWaterfall(props)Datadog/Jaeger-style distributed-trace waterfall. Renders each span as
a horizontal bar positioned by startTime, scaled to total trace
duration, indented by parent depth. A time axis is rendered along the
top with AXIS_TICK_COUNT evenly spaced ticks. Service name is shown
as a colored tag next to the operation name; bar color encodes status.
Styling is fully ClassMap-driven for layout. Only color attributes
(status colors, service-tag colors, bar fill) and pixel-perfect axis
geometry use inline style — these are properties ClassMap does not
model. Translations come from @molecule/app-locales-trace-waterfall.
Used by api-testing-tool, error-tracker, log-viewer, and any other developer tooling that consumes distributed-trace data.
function TraceWaterfall({
spans,
rootSpanId,
onSpanClick,
emptyState,
className,
}: TraceWaterfallProps): ReactElement<unknown, string | JSXElementConstructor<any>> | null
props — Component props.props.spans — Flat list of spans.props.rootSpanId — Optional focus span id.props.onSpanClick — Optional row-click callback.props.emptyState — Optional fallback when spans is empty.props.className — Extra classes for the root.Returns: The waterfall element tree.
Peer dependencies:
@molecule/app-react ^1.0.1@molecule/app-ui ^1.0.1@molecule/app-ui-react ^1.0.1react ^18.0.0 || ^19.0.0@molecule/app-react@molecule/app-ui@molecule/app-ui-reactreactDuration labels assume time values are MILLISECONDS: formatDurationLabel
renders values below 1 as microseconds and 1000+ as seconds, so
seconds-unit spans get wrong axis/row labels even though bar layout itself
is unit-agnostic — feed ms (or divide labels yourself). Bar status colors
and the 12-hue service palette are hardcoded hex (theme-independent,
legible in light + dark). The label column is fixed at 240px; long names
ellipsize. Rows are keyboard-activatable when onSpanClick is set.
Aria/empty-state strings come from the companion
@molecule/app-locales-trace-waterfall bond.
Translation strings are provided by @molecule/app-locales-trace-waterfall.