Creates a task collecting consecutive items into fixed-size batches.
Creates a task discarding repeated items.
Creates a task emitting the items a sink computes over the feed.
Creates a task retaining only the items matching a predicate.
Creates a task splicing nested feeds into a single feed, with or without a task opening the feeds to splice.
Creates a task interleaving several runs of another task over the same items.
Creates a task collecting items sharing the same key.
Creates a task interleaving nested feeds into a single feed, with or without a task opening the feeds to interleave.
Creates a task converting each item into a new value.
Creates a task observing the feed without altering it.
Creates a task discarding a prefix of the feed.
Creates a task reordering the feed.
Creates a task truncating the feed to a prefix.
Creates a task handing every item to several branches.
Intermediate operations that transform, filter or reshape the items of a feed.
Tasks apply to a Feed and yield a new feed, so they chain freely into longer pipes. Items are processed lazily, sequentially and in source order, unless a task reorders them, interleaves the nested feeds carrying them, hands each of them to several tasks at once or wraps another to run it concurrently, trading output order for throughput.
A task wrapping others either hands each of them the whole feed, as flat, join and tee do, leaving whatever state they initialise on invocation to decide on every item, or invokes one once per run over a share of the items, as fork does, scoping that state to the run rather than to the pipe as a whole. The feed a task draws from and the one it reports are both drained by a single pass, however repeatable the source behind them: a composition to be consumed twice is built afresh from the feed it opens with.
The item type of a task is taken from the feed it is applied to, or from the Task type it is declared under, never from the predicate, selector, mapper or comparator handed to it: a function accepting any item,
console.logorBooleanamong them, leaves the feed type untouched, while one accepting a different type is rejected. A task composed on its own, outside a pipe, states its item type in the type it is declared under or as an explicit type argument.Every task is classified along three axes:
An exhaustive task never completes on an infinite feed, and a materialising one may exhaust memory on a large feed, bounded or not. sort, group, an unbounded batch and a drain whose sink draws the feed entire are both; distinct, join and an uncapped fork are incremental yet materialising. Bound the feed upstream with take, batch by a positive size, or cap the runs of a fork.
A custom task is only required to report a feed honouring the Feed contract, however it is obtained: handing the generator object to items() is the shortest route there, while a transformation delegating to tasks already available composes the feed it draws from with them and reports what they report, a feed already. A transformation deciding on the feed as a whole is spared the generator altogether by drain, which carries on with the items a sink computes over it.
Custom Tasks extend a pipe, drawing the items of a feed and reporting a new one; the transformation is most easily written as an async generator handed to items(), with items to be dropped left unyielded: