Skip to Content
This documentation is provided with the HEAT environment and is relevant for this HEAT instance only.

Dataservice API

The Next dashboard loads analytics through a versioned envelope keyed $heat-dataservice. In Arbex, build it with heat.dataservice.createBuilder() and return buildRoot() when dataserviceOutput is enabled.

See also Next data service and direct ingestion.


Builder workflow

const ds = heat.dataservice.createBuilder({ version: "1.0", // optional, default "1.0" defaultRealm: "default", // optional }); ds.addGroup("analytics", "Analytics"); // required before channels ds.series( { id: "cpu", name: "CPU", groupId: "analytics", metadata: { units: "%" } }, [{ timeMs: 1000, value: 42 }], ); return ds.buildRoot(); // { $heat-dataservice, dashboard_users: [] }
StepAPIWhy
StartcreateBuilder(options?)Sets version and default realm
GroupaddGroup(id, name)UI channel picker sections; every channel needs a groupId
WriteShape helpers (below)Typed payloads per channel
FinishbuildRoot(opts?)Top-level object for persistence / dimension node

buildRoot options:

OptionEffect
suggestedLayoutConfiguration / layoutAttach v2 layout JSON or a heat.layout builder
dashboardUsers / dashboard_usersExternal user GUIDs when the script omits them

Channel shapes (when to use each)

ShapeMethodUse for
seriesds.series(spec, points)Time-varying values and playback ({ timeMs, value }[])
valueds.value(spec, payload)KPIs, tables, nested JSON ({ value: ... })
eventsds.events(spec, points)Instantaneous flags ({ timeMs, occurred }[])
timestampsds.timestamps(spec, points)Labelled instants ({ timeMs, annotation }[])
rangesds.ranges(spec, points)Phases and intervals (startTimeMs, endTimeMs, durationMs)

Rule: Structured data that is not a time series belongs in value, not fake series points.

Low-level ds.channel(spec, data) accepts any shape when you supply spec.shape and matching data.


Channel spec (per write)

FieldRequiredNotes
idYesStable id; layout channels arrays reference this string
nameYesDisplay label
groupIdYesMust match addGroup
realmNoOverrides builder defaultRealm
metadataNoHints: units, channelType, custom keys for widgets

Realms

Realms namespace channels (for example per trainee or per run). The same id in two realms is two different series.

  • Set defaultRealm on the builder or realm on each channel spec.
  • Keep realm count modest; dimension nodes can enforce limits.

Runtime vs types

The node host implements fluent helpers for series, value, events, timestamps, and ranges.

heat-arbex.d.ts also declares mapdisplay, flightpath, and responseTime. Those fluent methods are not on the host builder yet. Until they are, use ds.channel(spec, data) with the correct spec.shape and payload, or produce data upstream via another node template.


Example: all core shapes

async function run(ctx) { const ds = heat.dataservice.createBuilder({ version: "1.0", defaultRealm: "default" }); ds.addGroup("analytics", "Analytics"); ds.series( { id: "cpu-cores", name: "CPU cores", groupId: "analytics" }, [{ timeMs: 1000, value: 2.5 }, { timeMs: 2000, value: 3.1 }], ); ds.value( { id: "cluster-kpis", name: "Cluster KPIs", groupId: "analytics" }, { value: { podCount: 12, namespaceCount: 3 } }, ); ds.events( { id: "alerts", name: "Alerts", groupId: "analytics", realm: "alerts" }, [{ timeMs: 1500, occurred: true }], ); ds.timestamps( { id: "milestones", name: "Milestones", groupId: "analytics" }, [{ timeMs: 500, annotation: "Session start" }], ); ds.ranges( { id: "phases", name: "Phases", groupId: "analytics" }, [{ startTimeMs: 0, endTimeMs: 5000, durationMs: 5000 }], ); return ds.buildRoot(); }

Node config: dataserviceOutput.enabled: true, persistence: "dataservice-root". Full sample: dataservice-multi-shape.js.