A live current value for late readers
Requirement
A temperature feed pushes updates on a fixed schedule. A dashboard connects only after the first three updates have already gone by — it must still show the current value immediately (19.1 °C, the latest at join time), then every later update. The schedule is simulated in the code; both versions must print the lines shown under Expected output.
Expected output
joined late, current: 19.1 update: 19.5 update: 20.0
Side by side
RxDart
FxDart
Why they differ
They don't. "The latest value, replayed to whoever shows up"
is shared, multicast state, and fxdart has a dedicated
object for it too: LiveValue is
BehaviorSubject reduced to its defining behavior — a
sink the sensor writes to, a readable .value, and a feed
where a late subscriber first receives the most recent value, then
the live updates. Both panels are "add updates, subscribe late,
collect" — no hand-cached variable, no extra caching listener.
This is fxdart's events layer absorbing the Rx approach for
the push side: LiveValue.live hands back an
fxEvents chain — a thin wrapper over a plain broadcast
Stream, so it collides with nothing, rxdart included —
and .pull() crosses into the typed pull pipeline when
the per-value processing grows. RxDart's subject family and operator
catalog remain far larger; for latest-value-then-live itself, the
panels are equivalent: a tie.
Benchmark
No benchmark for this example. This operator is defined by elapsed time, not by work done: both sides wait out the same windows, so a bar would be measuring Dart's timers rather than either library. Shrinking the windows does not help either — how many values a burst produces would then depend on how fast the machine is, and the two sides could no longer be checked against an identical result. The examples built on timing operators are left unmeasured for that reason; the ones whose delays merely stand in for I/O are benchmarked with those delays set to zero.