github cyclejs/cyclejs v0.20.0
v0.20 - Streams: a dramatic breaking change

latest releases: unified-tag, v7.0.0, v7.0.0-rc8...
pre-release9 years ago

v0.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.

Don't miss a new cyclejs release

NewReleases is sending notifications on new releases.