Skip to content

Creating chains

run

run is used when we have a source at the same time we’re setting up the chain of processing.

Lets say we want a stream of x,y values from the ‘pointermove’ event. In this case, we know the source in advance, and we can specify one or more links to process the data.

// Set up the chain
const xy = Chains.run(
// Start with a source: in this case, event data
Chains.From.event(window, `pointermove`),
// Transform takes data from the previous link/source
// and returns data for the next link.
// In this case, we just pluck out the x,y values
Chains.Links.transform(event => ({ x:event.x, y:event.y }))
);

The return result of run is a regular Javascript asynchronous generator, see below for how to use the data.

A disadvantage of run is that the source is ‘baked-in’ to the definition, and you can’t reuse the chain with a different source.

prepare

If you don’t have a source ready, prepare allows you to define the chain and call it with a source later.

// Set up chain 'c'
const c = Chains.prepare(
Chains.Links.transform( v => Number.parseInt(v) ),
Chains.Links.filter(v => v % 2 === 0)
);
// Use 'c' with an array as a source, reading one item per 100ms
const results = c(Chains.From.array([1,2,3], 100));
for (const value of results) {
...
}

Chains made with prepare can be re-used with a different source:

// Reuse 'c' with a different source
const results = c(Chains.From.array([4,5,6], 100));

single

Chains are built of the idea of iterable data sources - several bits of data. However, there are cases where you want to use a chain for single input and expect a single output. Use single

// Create a chain that flattens values
const 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

Sources

Module Chains.From has various functions for creating chains.

Array

Items from an array can be a source, reading them one at a time with a given interval. Use: From.array

const someArray = [1,2,3,4,5];
// Read one item every 100ms
const c = Chains.From.array(someArray, 100);

Events

Event data can be a chain source. Specify the event target (eg a DOM element) and the name of the event. Use: From.event

const c = Chains.From.event(window, `pointermove`);

Example: Emits relative x,y coordinates

const xy = Chains.run(
Chains.From.event(window, `pointermove`),
Chains.Links.transform(event => ({
x:event.x/window.innerWidth,
y:event.y/window.innerHeight
}))
);

Timestamp

Generates the current time in milliseconds at a given interval. Use: From.timestamp

// Emits the time every second
const c = Chains.From.timestamp({ interval: 1000 });

By default it runs forever, but you can use loops or elapsed options to limit the number of times it runs

// Run 100 times
const c = Chains.From.timestamp({ interval: 1000, loops: 100 });
// Run for one minute
const c = Chains.From.timestamp({ interval: 1000, elapsed: 60*1000 });

Function

Repeatedly calls a function, yielding its values. Use: From.func

// Produces random values
const l = Chains.from.func(Math.random);

An example, yields five random numbers

import { Chains, toArray } from 'https://unpkg.com/ixfx/dist/iterables.js';
const chain = Chains.run(
Chains.From.func(Math.random),
Chains.Links.take(5)
);
toArray(chain);