cyclejs / cycle-time-travel

A time traveling debugger for Cycle.js
MIT License
217 stars 10 forks source link

npm version Build Status Code Climate


cycle-time-travel

cycle-time-travel is a time travelling stream viewer for Cycle.js apps.

Try the online example!

Why you should be excited:

A video is worth a thousand bullet points:

http://i.imgur.com/N5OMVzp.png

Okay, I'm in!

Great. Now just npm install cycle-time-travel and you can begin your mastery over time itself!

How do I use it?

The API is simple, and does two things. Displaying streams, and controlling time.

import makeTimeTravel from 'cycle-time-travel'

makeTimeTravel takes a DOM observable, and an array of streams to be displayed/controlled, in the form of {stream: stream$, label: 'stream$'}.

makeTimeTravel returns a DOM observable, and an object called timeTravel, with each of the streams you provided as an argument to makeTimeTravel available, keyed under the label.

Huh? Show me an example

Here is the counter example from the Cycle.js docs.

import Cycle from '@cycle/core';
import {h, makeDOMDriver} from '@cycle/dom';

function main({DOM}) {
  let action$ = Cycle.Rx.Observable.merge(
    DOM.select('.decrement').events('click').map(ev => -1),
    DOM.select('.increment').events('click').map(ev => +1)
  );

  let count$ = action$.startWith(0).scan((x,y) => x+y);

  return {
    DOM: count$.map(count =>
        h('div', [
          h('button.decrement', 'Decrement'),
          h('button.increment', 'Increment'),
          h('p', 'Counter: ' + count)
        ])
      )
  };
}

Cycle.run(main, {
  DOM: makeDOMDriver('#app')
});

And here it is with time travelling:

import Cycle from '@cycle/core';
import {h, makeDOMDriver} from '@cycle/dom';
import makeTimeTravel from 'cycle-time-travel';                 // NEW

function main({DOM}) {
  let action$ = Cycle.Rx.Observable.merge(
    DOM.select('.decrement').events('click').map(ev => -1),
    DOM.select('.increment').events('click').map(ev => +1)
  );

  let count$ = action$.startWith(0).scan((x,y) => x+y);

  let {DOM: timeTravelBar$, timeTravel} = makeTimeTravel(DOM, [ // NEW
    {stream: count$, label: 'count$'},                          // NEW
    {stream: action$, label: 'action$'}                         // NEW
  ]);                                                           // NEW

  return {
    DOM: Cycle.Rx.Observable.combineLatest(                     // NEW
      timeTravel.count$,                                        // NEW
      timeTravelBar$,                                           // NEW
      (count, timeTravelBar) =>                                 // NEW
        h('.app', [                                             
          h('div', [                                            
            h('button.decrement', 'Decrement'),
            h('button.increment', 'Increment'),
            h('p', 'Counter: ' + count)
          ]),

          timeTravelBar                                         // NEW
        ])
    )
  };
}

Cycle.run(main, {
  DOM: makeDOMDriver('#app')
});

There are a few things going on above:

That seems like a lot of work...

It might, but try it anyway! cycle-time-travel is in alpha so the API is still under development. If you have any feedback on how it could be easier to use, I'd love to hear it.

For more examples, see the /examples folder.

License

cycle-time-travel is available under the MIT license. See the LICENSE file for full text.

Contributing

I encourage and welcome contributions, be it pull requests, issues or just feedback. If in doubt, get in touch with me at ncwjohnstone@gmail.com