Live-plot data path: from queued NATS Scan payloads to a sorted, de-duplicated,
calibrated sample buffer per channel.
The streamer publishes one FlatBuffer Scan per channel per LabJack read, with the
time of the first value, the interval between values, and a batch sequence number
that restarts at 0 for each sampling run. Within a run, batches are contiguous: the
next batch starts one interval after the previous batch's last sample, give or take
a slew of at most half an interval, so timestamps are strictly increasing.
This module keeps the plot faithful to that stream:
ScanMessageQueue holds every received payload per channel until the next
UI tick, in arrival order. It is bounded; when full it drops the oldest message and
counts it, so an overload is visible instead of silent.
ingestScan turns one decoded scan into points. Each sample gets the time
first + i * interval, computed in integer nanoseconds. A NaN or LJM dummy
(-9999) sample becomes a NaN point, which the renderer draws as a gap. Missing
time between batches (lost or dropped messages, reconnects) gets a NaN gap marker
so the line is not bridged. Duplicate or late batches are skipped, and a timeline
that jumps backward (clock step, new run) resets the buffer instead of mixing two
timelines.
drainChannelQueue runs the above for every queued message of one channel,
in order, and appends to the channel's buffer.
Pure TypeScript with no Svelte or NATS dependency, so it is unit tested directly.
Live-plot data path: from queued NATS
Scanpayloads to a sorted, de-duplicated, calibrated sample buffer per channel.The streamer publishes one FlatBuffer
Scanper channel per LabJack read, with the time of the first value, the interval between values, and a batch sequence number that restarts at 0 for each sampling run. Within a run, batches are contiguous: the next batch starts one interval after the previous batch's last sample, give or take a slew of at most half an interval, so timestamps are strictly increasing.This module keeps the plot faithful to that stream:
first + i * interval, computed in integer nanoseconds. ANaNor LJM dummy (-9999) sample becomes aNaNpoint, which the renderer draws as a gap. Missing time between batches (lost or dropped messages, reconnects) gets aNaNgap marker so the line is not bridged. Duplicate or late batches are skipped, and a timeline that jumps backward (clock step, new run) resets the buffer instead of mixing two timelines.Pure TypeScript with no Svelte or NATS dependency, so it is unit tested directly.