Skip to content

Chains

Module Iterables.Chains

Chains are an ixfx way of working with iterable data. A chain is made up of links, each of which processes data in turn. A link is nothing more than a function which returns a generator. Sources are things that produce data for links to process.

Chains allow data flows to be encapsulated as generators with simple in-built semantics for consuming them. Other parts of your code don’t need to know what happens within the chain, or what kind of data source it uses - it just sees it as an iterable object that yields values and potentially finishes.

Why chains?

Here’s an example getting a stream of relative pointer coordinates.

First we need a function to convert absolute to relative coordinates based on viewport

const toRelative = (v) => ({
x: v.x/window.innerWidth,
y: v.y/window.innerHeight
});

Now we can employ chains:

const c = Chains.run(
Chains.From.event(document, `pointermove`),
Chains.Links.transform(toRelative)
)
for await (const v of c) {
console.log(v); // Prints out {x,y} on a 0..1 scale
}

You may wonder why it’s better than a more plain approach:

window.addEventListener(`pointermove`, v => {
const relative = toRelative(v);
console.log(relative);
})

The problem with the above approach is there’s no natural ‘flow’ for where the data should go. It needs to be encoded within the event handler, and if we need this to be dynamic, it adds complexity. Or if we want to use an alternative source of data, we’d have to refactor the code.

Using chains, the hope is that it’s easier to see the flow of data processing: we get data from the event, and then transform it.