A functional and reactive JavaScript framework for cleaner code
Tom Wilson
VP of Software Development Tabula Rasa Healthcare Jack Russell Software
function map (fn) {
return function (container) {
container.value = fn(container.value)
}
}
functions with no side effects
var a = 1
function add (b) {
return a + b
}
document.getElementById('#button')
.addEventListener('click', function (e) {
document
.getElementById('.text')
.innerText = 'Hello World'
})
Cycle.js is conceptionally maybe the best framework currently. "Best" in the sense of bug free, testability and logical structure. But for me it is really hard to write and understand. Too hard actually. I hope this changes in the future, too.
Observable.fromEvent(document.getElementById('.btn'), 'click')
.subscribe(function (ev) {
console.log('clicked')
})
function main (sources) {
return {
DOM: Observable.of({ title: 'Hello World'})
.map(state => h1(state.title))
}
}
run(main, {
DOM: makeDOMDriver('#app')
})
npm init
npm install rx @cycle/core @cycle/dom -S
<html>
...
<body>
<div id="app"></div>
...
</body>
</html>
import { Observable } from 'rx'
import { run } from '@cycle/core'
import { makeDOMDriver, div, h1, button, p } from '@cycle/dom'
run(main, {
DOM: makeDOMDriver('#app')
})
function main (sources) {
const counter = 0
const counter$ = DOM.select('.btn').events('click')
.map(e => counter + 1).startWith(0)
const state$ = Observable.of({ title: 'Hello World'})
return {
DOM: Observable.combineLatest(state$, counter$)
.map([state, counter] => div[
h1(state.title),
button('.btn', 'Add')
p('counter: ' + counter.toString())
])
}
}
npm install @cycle/http -S
import { makeHTTPDriver } from '@cycle/http'
function main (sources) {
const request$ = Observable.of({
url: DOC_URL,
method: 'GET'
})
const response$ = sources.HTTP
.filter(res$ => res$.request.url === DOC_URL).mergeAll()
.map(res => JSON.parse(res.text))
return {
DOM: response$
.map(data => div(JSON.stringify(data))),
HTTP: request$
}
}
function makeADriver () {
return function (input$) {
/*
Side Effects...
*/
return output$
}
}
function component (sources) {
...
const sinks = {
DOM: vtree$,
HTTP: request$
}
return sinks
}
function intent (sources) {
...
return actions$
}
function model (sources, actions) {
...
return model$
}
function view (model$) {
...
return vtree$
}
function component (sources) {
const actions$ = intent(sources)
return view(model(sources, actions$))
}