ecto-signals
A signals library for functional reactive programming.
Author: Tim Farland
Inspired by Elm and Bacon.js.
Written without the use of this
, new
, or prototype
- only simple objects and functions.
Miniscule size - ~1kb minified/gzipped.
License: MIT
Install
npm install --save ecto-signals
Test
npm test
Api
Signal type
Signal A :: {
listeners: [(A -> _)],
active: boolean,
value: A || null,
error: error || null
}
Creating signals
Capture events on a dom node.
const clicks = fromDomEvent(document.body, "click", evt => console.log(evt.target))
A signal that will emit one value, then terminate.
const later = fromCallback(callback => setTimeout(() => callback("Finished"), 1000))
A signal that will emit one value or an error from a Promise, then terminate.
const wait = fromPromise(new Promise(resolve => setTimeout(() => resolve("Finished"), 1000)))
A signal that emits an integer count of millisecond intervals since it was started.
const seconds = fromInterval(1000)
Low-level signal creation.
const rawSignal = create()
Interacting with signals
Subscribe to values emitted by the signal.
listen(clicks, e => console.log(e))
Send a value to a signal.
send(rawSignal, "value")
Stop a signal - no more values will be emitted.
stop(rawSignal)
Transforming signals
Map values of a signal
const values = map(evt => evt.target.value, fromDomEvent(input, "keydown"))
Map (zip) the latest value of multiple signals
const areas = map((x, y) => x * y, widthSignal, heightSignal)
Filter a signal, will only emit event that pass the test
const evens = filter(n => n % 2 === 0, numberSignal)
Only emit if the current value is different to the previous (as compared by ===
). Not a full deduplication.
dropRepeats(numbers)
Fold a signal over an initial seed value.
const sum = fold((a, b) => a + b, 0, numbersStream)
Merge many signals into one that emits values from all.
const events = merge(clicks, keypresses)
Take the last value of a stream when another stream emits.
const mousePositionsBySeconds = sampleOn(mousePosition, fromInterval(1000))
Emit an array of the last n values of a signal.
const trail = slidingWindow(5, mousePosition)
Map values of a signal to a new signal, then flatten the results of all emitted into one signal.
const responses = flatMap(evt => fromPromise(ajaxGet("/" + evt.target.value)), keyPresses)
The same as above, but only emits values from the latest child signal.
flatMapLatest(v => fromPromise(promiseCreator(v)), valueSignal)