Links
Links are the things you use when calling Chains.run() or Chains.prepare() . These are the little functions which work with data flowing through the chain, and pass it on to the next link.
Typically several links are used to make a chain. If you’ve only got one link, perhaps there is a simpler way to do it.
Here’s an overview of the in-built links:
- Math functions: min, max, average, sum, tally
- Filtering: filter, drop, rank, rankArray
- Changing the shape of values: chunk, reduce
- Timing of values: debounce, delay
- Stopping a chain: duration, take
min / max
Section titled “min / max”For every input value, min and max will always emit the smallest or largest value seen so far.
const ch = Chains.run( Chains.From.array([1,2,3,4]), Chains.Links.min();)// Produces 1, 1, 1, 1
Works with chains that output numbers or array of numbers. Non-numbers are skipped.
average()
Section titled “average()”Taking a numeric input (or array of numbers), average continuously returns a running average.
Chains.Links.average();
Non-numbers in the input stream are skipped.
Taking a numeric input (or array of numbers), sum returns the current total.
const ch = Chains.run( Chains.From.array([1,2,3,4]), Chains.Links.min();)// Produces 1, 3, 6, 10
Non-numbers in the input stream are skipped.
tally throws away the input value and instead emits the total number of values produced.
Example usage:
const ch = Chains.run( Chains.From.timestamp({ interval: 100 }), Chains.Links.tally());
for await (const v of ch) { // Produces: 1, 2, 3 ... every 100ms}
Filtering
Section titled “Filtering”filter
Section titled “filter”filter only passes values for which the predicate function returns true.
// Only allow even numbers to pass,// dropping all odd numbersChain.Links.filter(v => v % 2 === 0)
drop is the opposite of filter
. Instead dropping values which the predicate function returns true
// Drop all even numbers,// only allowing odd numbers to passChain.Links.drop(v => v % 2 === 0)
rank / rankArray
Section titled “rank / rankArray”rank allows values to be scored using some function, emitting the ‘best’ value. rankArray is the same, but it works within a set of values.
The ranking function gets two parameters, a
and b
, and is expected to return a string value denoting which is the best, or ‘eq’ if they are equal.
Eg, ranking objects based off a ‘size’ field:
Chains.Links.rank((a,b) => { if (a.size > b.size) return `a`; if (a.size < b.size) return `b`; return `eq`})
rank
has some options about when to emit a value downstream. By default, it won’t emit a new value if it’s equally ranked. And by default it won’t emit a value until it ‘beats’ the last value.
You can change these, for example:
Chains.Links.rank(fn, { emitEqualRanked: true, emitRepeatHighest: true});
rankArray works instead with arrays as input values. By default, it behaves similarly to rank
, but checks the contents of the array. If the withinArrays
option is set to true, it will instead emit the highest value within each array, and not care about previous values.
Changing shape
Section titled “Changing shape”transform
Section titled “transform”transform Takes an input value and returns an output value.
// Eg. return a doubled version of the input valueChains.Links.transform( v => v * 2 );
Example usage
const ch = Chains.run(Chains.From.array([1,2,3,4]), Chains.Links.transform( v => v * 2));for await (const v of ch) { // 2, 4, 6, 8}
reduce
Section titled “reduce”reduce assumes its input is an array, returning a single combined result using a function.
// Return the largest of the valuesChains.reduce(values => Math.max(...values));
Example usage
// Create a chain that flattens valuesconst reduce = Chains.reduce(values => Math.max(...values));
// Feed it a single input (an array), get a single output back:const result = await Chains.single(reduce, [ 1, 2, 3]); // 3
Given a stream of values, chunk breaks it up into arrays of a given length.
For example, given a chunk size of 3:
Chains.Links.chunk(3);
If the stream of input values is: 1, 2, 3, 4, 5, 6
we would get chunks of [ 1, 2, 3], [ 4, 5, 6 ]
By default, if the stream ends and a chunk is not complete, it is returned regardless. Set the second parameter to chunk
to false (ie Chains.Link.chunk(3, false)
) to instead throw away the under-sized chunk.
Timing
Section titled “Timing”delay changes the timing of the stream, allowing you to add delay before or after a value is yielded.
Chains.Links.delay({ before:1000 });Chains.Links.delay({ after:1000 });
Example usage
const ch = Chains.run(Chains.From.event(document, `click`), Chains.Links.delay({ before: 1000 }););for await (const v of ch) { // Runs 1s after a click}
debounce
Section titled “debounce”debounce ensures a minimum time between values. Values produced too quickly are dropped.
Chain.Links.debounce(100); // 100ms
Example usage:
const chain = Chains.run( // Produce values every 10ms for 350ms Chains.From.timestamp({ interval: 10, elapsed: 350 }), // Only let a value through every 100ms Chains.Links.debounce(100));
Stopping a chain
Section titled “Stopping a chain”take will return the input value, but will break the chain after a certain number of values flow through it.
// Stop after 5 resultsChains.Links.take(5);
Example usage:
// Handle five click events and then finishconst ch = Chains.run( Chains.From.event(document, `click`), Chains.Links.take(5))
The event will be unsubscribed automatically.
duration
Section titled “duration”duration will close a chain after a given interval has elapsed.
Chains.Links.duration(100); // 100ms