affluent
TypeScript icon, indicating that this package has built-in type declarations

0.2.0 • Public • Published

Affluent

A reactive stream primitive that natively supports other streams as input.

Say what?

This is a typical stream:

spring({ from: 0,  to: 100 })
  .start(v => v)

It accepts numbers and strings as props to affect the way it behaves, and emits values to a function.

An Affluent stream is the same, except those props can be other streams.

spring({
  from: 0,
  to: tween({ to: 100, yoyo: Infinity })
}).start(v => v)

Now every prop can be a dynamic stream.

These streams above don't exist yet, but when they do, they can be built with Affluent.

Install

npm install affluent

Use

A stream can be defined with the stream function.

import { stream } from 'affluent'

stream accepts two arguments: An initialisation function, and some default props.

stream(init, defaultProps)

The initialisation function returns an update function that will run once every frame that the stream is active.

Here's a basic stream that outputs how many frames its been running:

const frameCount = stream(() => {
  let count = 0

  return () => {
    count++
    return count
  }
})

This update function receives on argument, the stream's props.

If any of these props are also streams, those streams will be resolved prior to being passed to the update function.

Example

Given this stream:

const frameCount = stream(({ complete, initialProps }) => {
  let count = initialProps.initialCount

  return ({ increment }) => {
    count += increment
    return count
  }
}, {
  increment: 1,
  initialCount: 0 
})

If we now create frameCount:

frameCount().start(v => v)

We'll get a count of 1, 2, 3... etc, incrementing once per frame.

It's using the increment prop to increment by one each frame.

We can change this default using a prop:

frameCount({ increment: 2 }).start(v => v)
// 2, 4, 6...

But we can also set increment as another stream. In the following code, increment itself will increase by 1 every frame:

frameCount({
  increment: frameCount()
}).start(v => v)
// 1, 3, 6...

API

stream

stream defines a stream. It accepts two arguments, an initialisation function and some default props.

Initialisation function

This function is provided a single argument that contains three properties:

  • initialProps: The first props provided to the stream.
  • complete: This should be called to end the stream.
  • error: This should be called to throw an error.

The function should return an update function. This function runs once per frame. It is provided the latest resolved props, and should return the latest value to emit from the stream.

const frameCount = stream(({ complete, initialProps }) => {
  let count = initialProps.initialCount

  return ({ increment }) => {
    count += increment
    return count
  }
}, {
  increment: 1,
  initialCount: 0 
})

The function can optionally return an object with both update and complete functions. complete will be fired either when the stream completes itself, or if its stopped externally.

Stream instance

start

Returns an active stream with a stop method.

It can be provided a function that fires when the stream emits values:

frameCount().start(v => { /* 1, 2, 3... */})

Or an object that defines update and/or complete functions:

frameCount().start({
  update: v => {/* 1, 2, 3... */},
  complete: () => console.log('complete!')
})

pipe

Creates a new stream instance that runs all output through the functions provided to pipe, in order:

const double = v => v * 2

frameCount()
  .pipe(double)
  .start(/* 2, 4, 6... */)

Active stream

The active stream returned from start.

stop

Stops the stream.

const active = frameCount().start(v => v)

active.stop()

Readme

Keywords

none

Package Sidebar

Install

npm i affluent

Weekly Downloads

0

Version

0.2.0

License

MIT

Unpacked Size

62.1 kB

Total Files

22

Last publish

Collaborators

  • popmotion