Cycle.js
Dialogue Abstraction

Human-Computer Interaction is a dialogue: an ongoing exchange of messages between the two parts.
function human(senses) {
// define the behavior of `actuators` somehow
return actuators; // this may be an observer, event emmitter or similar
}
function computer(senses) {
// define the behavior of `outputs` somehow
return actuators; // this may be an observer, event emmitter or similar
}
var screenEvents = computer(interactionEvents);
var interactionEvents = human(screenEvents);
// uh oh!
var screenEvents = computer(human(screenEvents));
Fixed point of a function
In mathematics, a fixed point (sometimes shortened to fixpoint, also known as an invariant point) of a function is an element of the function's domain that is mapped to itself by the function.
function human(senses) {
// define the behavior of `actuators` somehow
return actuators; // this may be an observer, event emmitter or similar
}
function computer(senses) {
// define the behavior of `outputs` somehow
return actuators; // this may be an observer, event emmitter or similar
}
var interactionEvents1 = new emptyStream();
// now we can get screenEvents
var screenEvents = computer(interactionEvents1);
// with screen events we can get the interactionEvents
var interactionEvents = human(screenEvents);
// forward that to the original interaction event stream
interactionEvents.listen(function(e) {
interactionEvents1.emit(e);
});
/*function human(senses) {
// define the behavior of `actuators` somehow
return actuators; // this may be an observer, event emmitter or similar
}*/
/*function computer(senses) {
// define the behavior of `outputs` somehow
return actuators; // this may be an observer, event emmitter or similar
}*/
// var interactionEvents1 = new emptyStream();
// now we can get screenEvents
var screenEvents = computer(interactionEvents1);
// with screen events we can get the interactionEvents
// var interactionEvents = human(screenEvents);
// forward that to the original interaction event stream
/*interactionEvents.listen(function(e) {
interactionEvents1.emit(e);
});*/
Cycle’s core abstraction is your application as a pure function main() where inputs are read effects (sources) from the external world and outputs (sinks) are write effects to affect the external world.
These side effects in the external world are managed by drivers: plugins that handle DOM effects, HTTP effects, etc.
In short, we want to be able to properly separate logic from effects.
Cycle.js is...
- Functional and Reactive
- Simple and Concise
- Extensible and Testable
Functional and Reactive
Cycle.js apps are made of pure functions, which means you know they simply take inputs and generate outputs, without performing any side effects.
The building blocks are Observables from RxJS. Structuring the application with RxJS also separates concerns, because all dynamic updates to a piece of data are co-located and impossible to change from outside.
As a result, apps in Cycle are entirely this-less and have nothing comparable to imperative calls such as setState() or foo.update().
Simple and Concise
The core API has just one function: run(app, drivers). Besides that, there are Observables, functions, drivers (plugins for different types of side effects), and a helper function to isolate scoped components.
Extensible and Testable
Drivers are plugin-like simple functions that take messages from sinks and call imperative functions. All side effects are contained in drivers. This means your application is just a pure function, and it becomes easy to swap drivers around.
The application is a simple transformation of data.
Explicit data flow

Drivers
Drivers are functions that listen to Observable sinks (their input), perform imperative side effects, and may return Observable sources (their output).
Model View Intent
MVI, the new MVC
- Intent (listen to the user)
- Model (to process information)
- View (output back to the user)
The essential purpose of MVC is to bridge the gap between the human user’s mental model and the digital model that exists in the computer.
– Trygve Reenskaug, inventor of MVC
Classic MVC

How does MVI compare to MVC?
Model-View-Intent (MVI) is reactive, functional, and follows the core idea in MVC.
It is reactive because Intent observes the User, Model observes the Intent, View observes the Model, and the User observes the View.
It is functional because each of these components is expressed as a referentially transparent function over Observables.
It follows the original MVC purpose because View and Intent bridge the gap between the user and the digital model, each in one direction.
Show me the CODE!
Cycle.js basic code for a counter
Let's build a clone!

Getting the basics right
First thing we want to do is to actually add the necessary code to create a counter using nothing more than vanilla JS (ES6) and RxJS.
Making it more generic
Experimenting with techniques to remove hard coded dependencies in our toy version.
The infinite loop problem
Using an empty Rx subject to solve the infinite loop problem.
A more generic run function
Separating our run function and making it a little bit more generic by automating proxies and and subscriptions.
Using cycle.js, part 1
Adding @cycle/core and making our toy DOM driver a little bit more generic.
Using cycle.js, part 2
Using @cycle/core and creating helper functions to address html rendering.
Adding the real DOM driver
Removing the drivers.js file and adding the official @cycle/dom driver
Model View Intent
Refactoring our implementation to use MVI pattern and properly separate concerns.
Or, clone:

Cycle
By Carlos Vega
Cycle
- 702