Which surface?
Four surfaces, one import. Pick the surface the job is, then stay on it.
Lecture
FxDart is not four libraries in a trenchcoat. It is one package because a real program crosses these jobs, and the names stay the same when you do. The mistake is starting from a function list. Start from the job:
| The job is… | Start with | Not |
|---|---|---|
| Data already in hand; only part of it is needed | fx(iterable) |
wrapping a one-line map/where/take |
| I/O over a known collection, at most n in flight, order kept | .toAsync().map(f).concurrent(n) or .mapConcurrent(n, f) |
Future.wait(xs.map(f)) |
| Values arrive when they arrive (keystrokes, ticks, sockets) | fxEvents(stream) |
a pull pipeline with sleep |
| The caller handles the failure | either / mapEither / attempt on the surface you are already on |
throw for domain errors; null with the reason lost |
Pull names win collisions. takeUntil is the FxTS predicate;
the events-layer analogue is stopOn.
One word, one meaning. Cross at a named seam:
.toAsync() lifts data into demand,
.pull() lifts events into demand,
.toStream() goes the other way.
attempt after
retryOn /
retryOnError, never before. Those operators watch the
error channel; once a failure is a Left there is nothing
left there to retry.
Two jobs that cross surfaces are worked as tutorials of their own:
debounced search (time → latest query
wins → typed parse) and
bounded concurrent fetch (a bound, order
kept, every failure kept). The pull on-ramp still starts at
fx.
Demo · four jobs, four surfaces
The same import. Each block is the smallest program that belongs on that row of the table:
fx — the pull chain ·
concurrent — the I/O bound ·
fxEvents — the push chain ·
typed errors — failures as values ·
debounced search ·
bounded concurrent fetch