LiveValue
A live "current value" with subscribers: a late subscriber immediately receives the latest value, then every update after it.
Lecture
A plain Stream has no memory: subscribe late and you get
nothing until the next event, which for state — the current user, the
current temperature, the current zoom — means every new screen starts
blank. LiveValue<T> is state done as an event
source: it holds a current value, add updates it and
notifies subscribers, and every late subscriber replays the
latest value first, then rides the live updates. No gap, no
blank start, no "wait for the next tick".
The API is deliberately small. Construct empty (LiveValue())
or with a seed (LiveValue.seeded(value)). Read
synchronously with .value — which throws a
StateError when nothing has been set, so check
.hasValue or seed it; there is no silent null
pretending to be state. Subscribe through .live, which is
an FxEvents chain (map it,
debounce it, combine it), or .stream for the plain-Stream
view of the same feed.
close() ends the feed: subscribers' streams close, and a
later add throws — though even a closed
LiveValue still replays its last value to a late
subscriber before closing their stream. If you know Rx, this is
BehaviorSubject reduced to its defining behavior;
fxdart events layer, not part of FxTS.
Demo 1 · Late subscribers start from the latest value
Demo 2 · value, hasValue, and close
Method spelling
A Stream reaches both constructors as members:
source.fxLive is LiveValue.from(source), and
source.fxLiveSeeded(v) is
LiveValue.seededFrom(v, source). Both are still hot — the
subscription opens on the spot.
final price = ticker.fxLive;
final count = taps.fxLiveSeeded(0); // has a value before the first tap
Try it yourself
Exercise: derive a label feed from live state.
fxEvents — .live speaks this chain natively ·
combineLatest — deriving state from two live feeds ·
Stream bridges — carrying the feed into the pull world