v0.20 - Streams: a dramatic breaking change
Pre-releasev0.20 is unfortunately or fortunately a "this changes everything" version. We removed: DataFlowNode, DataFlowSink, DataFlowSource, Model, View, Intent, DOMUser. New API is just: render(), createStream(), and the familiar registerCustomElement().
Streams are a core part of Cycle now, and everything you need to know about them are explained here.
The rationale is: where DataFlowNode supported multiple output Observables, a Stream supports only one output Observable because a Stream is an Observable. The benefit with this new API is the removal of getters, and a rather simpler abstraction since you only need to think of how to compose Streams.
A single-output DataFlowNode is replaced by a Stream.
A single-input DataFlowSink is replaced by just a subscriber to an Observable.
A single-output DataFlowSource is replaced by a normal Rx.Observable.
BEFORE
let FooNode = Cycle.createDataFlowNode(function (BarNode) {
return {
foo$: BarNode.get('bar$').map(bar => 'This is bar: ' + bar)
};
});AFTER
let foo$ = Cycle.createStream(function (bar$) {
return bar$.map(bar => 'This is bar: ' + bar);
});The DOMUser was a DataFlowNode, hence it was "function-like". Now the user is just a normal JS function implemented by the developer. Cycle as a framework provides render(vtree$, container), which just outputs rootElem$, an Observable emitting the DOM element rendered from vtree$ into the given container. This rootElem$ is special in that it contains a reference to another Observable: rootElem$.interaction$, representing all possible events from all children elements under the root element. You filter on interaction$ by calling choose(selector, eventName). This is how a user is represented in Cycle v0.20:
let interaction$ = Cycle.createStream(function user(vtree$) {
return Cycle.render(vtree$, '.js-container').interaction$;
});Custom elements are still registered globally with registerCustomElement(tagName, definitionFn), but the definitionFn is expected to have a different signature. definitionFn(rootElem$, props) is the signature, where rootElem$ is a Cycle Stream which should be injected a vtree$ that you should create inside the definitionFn. Properties are accessible using their dollar name on the props object. Unfortunately you must use a getter with the props object: props.get('color$'), while ES6 proxies are still unfeasible. See this example of a custom element.
Read the (short!) API documentation, check out examples and open issues or join the gitter channel for questions and feedback.