0.0.8 • Published 10 years ago
event-flow v0.0.8
Event Flow
npm install --save event-flow
Functional JavaScript event plumbing
Event Flow is a declarative syntax for expressing how data moves through functions.
Quick overview
- Define an event as a function that 1) is called with other functions, and 2) calls those other functions in the future. Let's call those other functions "delegates". This model is consistent with how Redux's
store.subscribefunction behaves. - Delegates come in two flavors. 1) One is defined by
.call( ... )which simply calls the given function, and 2) the other is defined by.pipe( ... ).to( ... ), which calls thepipefunction with thetofunction. The advantage of approach #2 is that you can generalize how data flows to thetofunction. Thepipemay choose to call it once, never, many times, after a Promise is resolved, etc... depending on the event arguments. And, the logic of how data flows to thetofunction is decoupled from the function itself. For example, you could calltowith Reduxstore.dispatchif you're piping actions.
API
createEvent(event)
eventis a function of a function, e.g. Reduxstore.subscribe.- Returns a new instance of the
EventFlowclass. - (Note: All methods of
EventFloware composable, meaning that they all returnthis.)
EventFlow.pass(source)
sourceis a function called at event time. Its return value is passed as an argument to each event delegate. Ifpassis called multiple times, then multiple arguments will be passed in the order of the calls.- Returns
this.
EventFlow.call(delegate)
delegateis a function called at event time with arguments.- Returns
this.
EventFlow.pipe(delegate)
delegateis a function called at event time with a "yield" function, plus arguments.delegatemay asynchronously call the "yield" function, which is defined by the next call toEventFlow.to.- Returns
this.
EventFlow.to(yield_function)
- Defines the yield function passed to a
pipedelegate, which is defined by the previous call toEventFlow.pipe. - Returns
this.
Simple example with Redux
import { createEvent } from 'event-flow';
import { createStore } from 'redux';
const store = createStore((state = 0, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1;
case 'RESET':
return 0;
default:
return state;
}
});
const actions = (push, state) => {
if (state === 10) {
push({ type: 'RESET' });
setTimeout(() => push({ type: 'RESET' }), 500);
}
};
// Create a simple event flow that dispatches actions after a change to state (and logs the state).
createEvent(store.subscribe)
.pass(store.getState)
.call(state => console.log(`state = ${state}`))
.pipe(actions).to(store.dispatch);
// Dispatch INCREMENT actions every 100ms.
setInterval(() => store.dispatch({ type: 'INCREMENT' }), 100);
Console output:
state = 1
state = 2
state = 3
state = 4
state = 5
state = 6
state = 7
state = 8
state = 9
state = 10
state = 0
state = 1
state = 2
state = 3
state = 4
state = 0
state = 1
state = 2
state = 3
state = 4
state = 5
state = 6
state = 7
state = 8
state = 9
state = 10
state = 0
state = 1
state = 2
state = 3
state = 4
state = 0
state = 1
state = 2
state = 3
state = 4
state = 5
state = 6
state = 7
state = 8
state = 9
state = 10
state = 0
etc...