Cycle.js
Who am I?
Arye Lukashevski
Software Engineer @ Wix.com
Intro
What’s Reactive programming?
Foo depends on Bar
But who owns the relationship?
Foo Bar
Proactive
• Foo invokes the action
• Bar has an API for interaction
• ‘Find usages’
Foo Bar
Proactive Passive
function	onClick()	{	
	Bar.increment();	
}	
Foo
Foo Bar
Listenable Reactive
Foo.addSub('click',	()	=>	{	
	self.increment();	
});	
Bar
Reactive
• Foo emits events
• Bar subscribes
• Bar changes its state
A B
1 0 =A1 + A2
2 0 0
What’s Reactive programming?
A B
1 2 =A1 + A2
2 3 0
What’s Reactive programming?
A B
1 2 5
2 3 0
What’s Reactive programming?
Cycle.JS
Fully Reactive framework
RxJS as stream handlers
DOMDriver
main(DOM){
return fn(DOM);
}
Cycle.js data flow
DOMDriver
main(DOM){
return fn(DOM);
}
Event
Cycle.js data flow
DOMDriver
main(DOM){
return fn(DOM);
}
Event
Cycle.js data flow
DOMDriver
main(DOM){
return fn(DOM);
}
Event
Cycle.js data flow
DOMDriver
main(DOM){
return fn(DOM);
}
Event
Cycle.js data flow
DOMDriver
main(DOM){
return fn(DOM);
}
Event<li/>…<li/>
Cycle.js data flow
DOMDriver
main(DOM){
return fn(DOM);
}
<li/>…<li/>
Cycle.js data flow
DOMDriver
main(DOM){
return fn(DOM);
}
<li/>…<li/>
Cycle.js data flow
DOMDriver
main(DOM){
return fn(DOM);
}
<li/>…<li/>
Cycle.js data flow
DOMDriver
main(DOM){
return fn(DOM);
}
Cycle.js data flow
DOMDriver
main(DOM){
return fn(DOM);
}
Cycle.js data flow
DOMDriver
main(DOM){
return fn(DOM);
}
Cycle.js data flow
Demo - Pizza topping selection
Demo light - Checkbox
let main = ({DOM}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked)

.startWith(false);

const view$ = model$.map(toggled =>

div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

return {DOM: view$};

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

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked)

.startWith(false);

const view$ = model$.map(toggled =>

div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

return {DOM: view$};

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



















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

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked)

.startWith(false);

const view$ = model$.map(toggled =>

div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

return {DOM: view$};

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


div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

let main = ({DOM}) => {



















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

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked)

.startWith(false);

const view$ = model$.map(toggled =>

div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

return {DOM: view$};

};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
const intent$ = DOM.select('input').events('change');


div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

let main = ({DOM}) => {



















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

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked)

.startWith(false);

const view$ = model$.map(toggled =>

div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

return {DOM: view$};

};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
const intent$ = DOM.select('input').events('change');
const model$ = intent$.map(ev => ev.target.checked)



div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

let main = ({DOM}) => {



















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

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked)

.startWith(false);

const view$ = model$.map(toggled =>

div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

return {DOM: view$};

};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
const intent$ = DOM.select('input').events('change');
const model$ = intent$.map(ev => ev.target.checked)



div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

let main = ({DOM}) => {



















};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
const view$ = model$.map(toggled =>









return {DOM: view$};
let main = ({DOM}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked)

.startWith(false);

const view$ = model$.map(toggled =>

div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

return {DOM: view$};

};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
const intent$ = DOM.select('input').events('change');
const model$ = intent$.map(ev => ev.target.checked)



div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

let main = ({DOM}) => {



















};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
.startWith(false);
const view$ = model$.map(toggled =>









return {DOM: view$};
let main = ({DOM}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked)

.startWith(false);

const view$ = model$.map(toggled =>

div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

return {DOM: view$};

};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
const intent$ = DOM.select('input').events('change');
const model$ = intent$.map(ev => ev.target.checked)



div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

let main = ({DOM}) => {



















};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
.startWith(false);
const view$ = model$.map(toggled =>









return {DOM: view$};
let main = ({DOM}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked)

.startWith(false);

const view$ = model$.map(toggled =>

div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

return {DOM: view$};

};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
const intent$ = DOM.select('input').events('change');
const model$ = intent$.map(ev => ev.target.checked)



div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

let main = ({DOM}) => {



















};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
.startWith(false);
const view$ = model$.map(toggled =>









return {DOM: view$};
let main = ({DOM}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked)

.startWith(false);

const view$ = model$.map(toggled =>

div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

return {DOM: view$};

};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
const intent$ = DOM.select('input').events('change');
const model$ = intent$.map(ev => ev.target.checked)



div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

let main = ({DOM}) => {



















};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
.startWith(false);
const view$ = model$.map(toggled =>









return {DOM: view$};
Driver
Intent$
model$
view$
Driver
Intent$
model$
view$
checked:	true,	
target:	input
Driver
Intent$
model$
view$
checked:	true,	
target:	input
Driver
Intent$
model$
view$
checked:	true,	
target:	input
Driver
Intent$
model$
view$
Driver
Intent$
model$
view$
true
Driver
Intent$
model$
view$true
Driver
Intent$
model$
view$
Driver
Intent$
model$
view$<input type=“checkbox” …>
Driver
Intent$
model$
view$
<input type=“checkbox” …>
Driver
Intent$
model$
view$
Driver
Intent$
model$
view$
Component
• Cycle app can be used as a component in a larger Cycle app
const main = ({DOM}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked)

.startWith(false);

const view$ = model$.map(toggled =>

div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

return {DOM: view$};

};
const main = ({DOM}) => ({DOM:...});
const Toggle = ({DOM}) => ({DOM:...});
const Toggle = ({DOM}) => ({DOM:...});
const main = ({DOM}) => {

























};
const Toggle = ({DOM}) => ({DOM:...});
const main = ({DOM}) => {

const toggleOlives = Toggle({DOM});























};
const Toggle = ({DOM}) => ({DOM:...});
const main = ({DOM}) => {

const toggleOlives = Toggle({DOM});

const toggleMushrooms = Toggle({DOM});




















};
const Toggle = ({DOM}) => ({DOM:...});
const main = ({DOM}) => {

const toggleOlives = Toggle({DOM});

const toggleMushrooms = Toggle({DOM});
const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM,



















};
const Toggle = ({DOM}) => ({DOM:...});
const main = ({DOM}) => {

const toggleOlives = Toggle({DOM});

const toggleMushrooms = Toggle({DOM});
const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM,
(toggleOlives, toggleMushrooms) =>

div([

toggleOlives,

toggleMushrooms

])

);






};
const Toggle = ({DOM}) => ({DOM:...});
const main = ({DOM}) => {

const toggleOlives = Toggle({DOM});

const toggleMushrooms = Toggle({DOM});
const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM,
(toggleOlives, toggleMushrooms) =>

div([

toggleOlives,

toggleMushrooms

])

);
return {

DOM: view$

}

};
DOM.select('input')const Toggle = ({DOM}) => ({DOM:...});
const main = ({DOM}) => {

const toggleOlives = Toggle({DOM});

const toggleMushrooms = Toggle({DOM});
const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM,
(toggleOlives, toggleMushrooms) =>

div([

toggleOlives,

toggleMushrooms

])

);
return {

DOM: view$

}

};
const Toggle = ({DOM}) => ({DOM:...});
const main = ({DOM}) => {

const toggleOlives = Toggle({DOM: DOM.select('.olives')});

const toggleMushrooms = Toggle({DOM});
const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM,
(toggleOlives, toggleMushrooms) =>

div([

toggleOlives,

toggleMushrooms

])

);
return {

DOM: view$

}

};
const Toggle = ({DOM}) => ({DOM:...});
const main = ({DOM}) => {

const toggleOlives = Toggle({DOM: DOM.select('.olives')});

const toggleMushrooms = Toggle({DOM});
const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM,
(toggleOlives, toggleMushrooms) =>

div([

div('.olives', [toggleOlives]),

toggleMushrooms

])

);
return {

DOM: view$

}

};
const Toggle = ({DOM}) => ({DOM:...});
const main = ({DOM}) => {

const toggleOlives = Toggle({DOM: DOM.select(‘.olives')});
const toggleMushrooms = Toggle({DOM: DOM.select('.mushrooms')});

const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM,

(toggleOlives, toggleMushrooms) =>

div([

div('.olives', [toggleOlives]),

div('.mushrooms', [toggleMushrooms])

])

);

return {

DOM: view$

}

};
Component I/O
const props$ = $.of({

name: 'Pineapple'

})
const props$ = $.of({

name: 'Pineapple'

})
const Toggle = ({DOM, }) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked).startWith(false);

const view$ = $.combineLatest(model$,

(toggled, ) =>

div([input({type: 'checkbox'}),

,

p(toggled ? 'ON' : 'off')]));

return {

DOM: view$, 



}

};
const props$ = $.of({

name: 'Pineapple'

})
const Toggle = ({DOM, props$}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked).startWith(false);

const view$ = $.combineLatest(model$, 

(toggled, ) =>

div([input({type: 'checkbox'}),

,

p(toggled ? 'ON' : 'off')]));

return {

DOM: view$, 



}

};
const props$ = $.of({

name: 'Pineapple'

})
const Toggle = ({DOM, props$}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked).startWith(false);

const view$ = $.combineLatest(model$, props$,

(toggled, ) =>

div([input({type: 'checkbox'}),

,

p(toggled ? 'ON' : 'off')]));

return {

DOM: view$, 



}

};
const props$ = $.of({

name: 'Pineapple'

})
const Toggle = ({DOM, props$}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked).startWith(false);

const view$ = $.combineLatest(model$, props$,

(toggled, props) =>

div([input({type: 'checkbox'}),

,

p(toggled ? 'ON' : 'off')]));

return {

DOM: view$, 



}

};
const props$ = $.of({

name: 'Pineapple'

})
const Toggle = ({DOM, props$}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked).startWith(false);

const view$ = $.combineLatest(model$, props$,

(toggled, props) =>

div([input({type: 'checkbox'}),

props.name,

p(toggled ? 'ON' : 'off')]));

return {

DOM: view$, 



}

};
const props$ = $.of({

name: 'Pineapple'

})
const Toggle = ({DOM, props$}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked).startWith(false);

const view$ = $.combineLatest(model$, props$,

(toggled, props) =>

div([input({type: 'checkbox'}),

props.name,

p(toggled ? 'ON' : 'off')]));

return {

DOM: view$, 

value$: model$
}

};
const props$ = $.of({

name: 'Pineapple'

})
const Toggle = ({DOM, props$}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked).startWith(false);

const view$ = $.combineLatest(model$, props$,

(toggled, props) =>

div([input({type: 'checkbox'}),

props.name,

p(toggled ? 'ON' : 'off')]));

return {

DOM: view$, 

value$: model$
}

};
const props$ = $.of({

name: 'Pineapple'

})
toggleOlives.value$.map(...)
Next
• More Drivers: HTTP, Storage, React Native
• HTML to hyperscript
• cyc - Generator
• awesome-cyclers: Lots of info
Questions?
Thank you!

Cyclejs introduction

  • 1.
  • 2.
    Who am I? AryeLukashevski Software Engineer @ Wix.com
  • 3.
  • 4.
    What’s Reactive programming? Foodepends on Bar But who owns the relationship? Foo Bar
  • 5.
    Proactive • Foo invokesthe action • Bar has an API for interaction • ‘Find usages’ Foo Bar Proactive Passive function onClick() { Bar.increment(); } Foo
  • 6.
  • 7.
    A B 1 0=A1 + A2 2 0 0 What’s Reactive programming?
  • 8.
    A B 1 2=A1 + A2 2 3 0 What’s Reactive programming?
  • 9.
    A B 1 25 2 3 0 What’s Reactive programming?
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
    Demo - Pizzatopping selection
  • 24.
    Demo light -Checkbox
  • 25.
    let main =({DOM}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked)
 .startWith(false);
 const view$ = model$.map(toggled =>
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 return {DOM: view$};
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') });
  • 26.
    let main =({DOM}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked)
 .startWith(false);
 const view$ = model$.map(toggled =>
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 return {DOM: view$};
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); let main = ({DOM}) => {
 
 
 
 
 
 
 
 
 
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') });
  • 27.
    let main =({DOM}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked)
 .startWith(false);
 const view$ = model$.map(toggled =>
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 return {DOM: view$};
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); 
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 let main = ({DOM}) => {
 
 
 
 
 
 
 
 
 
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') });
  • 28.
    let main =({DOM}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked)
 .startWith(false);
 const view$ = model$.map(toggled =>
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 return {DOM: view$};
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); const intent$ = DOM.select('input').events('change'); 
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 let main = ({DOM}) => {
 
 
 
 
 
 
 
 
 
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') });
  • 29.
    let main =({DOM}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked)
 .startWith(false);
 const view$ = model$.map(toggled =>
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 return {DOM: view$};
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); const intent$ = DOM.select('input').events('change'); const model$ = intent$.map(ev => ev.target.checked)
 
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 let main = ({DOM}) => {
 
 
 
 
 
 
 
 
 
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') });
  • 30.
    let main =({DOM}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked)
 .startWith(false);
 const view$ = model$.map(toggled =>
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 return {DOM: view$};
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); const intent$ = DOM.select('input').events('change'); const model$ = intent$.map(ev => ev.target.checked)
 
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 let main = ({DOM}) => {
 
 
 
 
 
 
 
 
 
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); const view$ = model$.map(toggled =>
 
 
 
 
 return {DOM: view$};
  • 31.
    let main =({DOM}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked)
 .startWith(false);
 const view$ = model$.map(toggled =>
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 return {DOM: view$};
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); const intent$ = DOM.select('input').events('change'); const model$ = intent$.map(ev => ev.target.checked)
 
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 let main = ({DOM}) => {
 
 
 
 
 
 
 
 
 
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); .startWith(false); const view$ = model$.map(toggled =>
 
 
 
 
 return {DOM: view$};
  • 32.
    let main =({DOM}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked)
 .startWith(false);
 const view$ = model$.map(toggled =>
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 return {DOM: view$};
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); const intent$ = DOM.select('input').events('change'); const model$ = intent$.map(ev => ev.target.checked)
 
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 let main = ({DOM}) => {
 
 
 
 
 
 
 
 
 
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); .startWith(false); const view$ = model$.map(toggled =>
 
 
 
 
 return {DOM: view$};
  • 33.
    let main =({DOM}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked)
 .startWith(false);
 const view$ = model$.map(toggled =>
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 return {DOM: view$};
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); const intent$ = DOM.select('input').events('change'); const model$ = intent$.map(ev => ev.target.checked)
 
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 let main = ({DOM}) => {
 
 
 
 
 
 
 
 
 
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); .startWith(false); const view$ = model$.map(toggled =>
 
 
 
 
 return {DOM: view$};
  • 34.
    let main =({DOM}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked)
 .startWith(false);
 const view$ = model$.map(toggled =>
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 return {DOM: view$};
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); const intent$ = DOM.select('input').events('change'); const model$ = intent$.map(ev => ev.target.checked)
 
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 let main = ({DOM}) => {
 
 
 
 
 
 
 
 
 
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); .startWith(false); const view$ = model$.map(toggled =>
 
 
 
 
 return {DOM: view$};
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
    Component • Cycle appcan be used as a component in a larger Cycle app
  • 48.
    const main =({DOM}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked)
 .startWith(false);
 const view$ = model$.map(toggled =>
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 return {DOM: view$};
 };
  • 49.
    const main =({DOM}) => ({DOM:...});
  • 50.
    const Toggle =({DOM}) => ({DOM:...});
  • 51.
    const Toggle =({DOM}) => ({DOM:...}); const main = ({DOM}) => {
 
 
 
 
 
 
 
 
 
 
 
 
 };
  • 52.
    const Toggle =({DOM}) => ({DOM:...}); const main = ({DOM}) => {
 const toggleOlives = Toggle({DOM});
 
 
 
 
 
 
 
 
 
 
 
 };
  • 53.
    const Toggle =({DOM}) => ({DOM:...}); const main = ({DOM}) => {
 const toggleOlives = Toggle({DOM});
 const toggleMushrooms = Toggle({DOM}); 
 
 
 
 
 
 
 
 
 
 };
  • 54.
    const Toggle =({DOM}) => ({DOM:...}); const main = ({DOM}) => {
 const toggleOlives = Toggle({DOM});
 const toggleMushrooms = Toggle({DOM}); const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM,
 
 
 
 
 
 
 
 
 
 };
  • 55.
    const Toggle =({DOM}) => ({DOM:...}); const main = ({DOM}) => {
 const toggleOlives = Toggle({DOM});
 const toggleMushrooms = Toggle({DOM}); const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM, (toggleOlives, toggleMushrooms) =>
 div([
 toggleOlives,
 toggleMushrooms
 ])
 ); 
 
 
 };
  • 56.
    const Toggle =({DOM}) => ({DOM:...}); const main = ({DOM}) => {
 const toggleOlives = Toggle({DOM});
 const toggleMushrooms = Toggle({DOM}); const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM, (toggleOlives, toggleMushrooms) =>
 div([
 toggleOlives,
 toggleMushrooms
 ])
 ); return {
 DOM: view$
 }
 };
  • 57.
    DOM.select('input')const Toggle =({DOM}) => ({DOM:...}); const main = ({DOM}) => {
 const toggleOlives = Toggle({DOM});
 const toggleMushrooms = Toggle({DOM}); const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM, (toggleOlives, toggleMushrooms) =>
 div([
 toggleOlives,
 toggleMushrooms
 ])
 ); return {
 DOM: view$
 }
 };
  • 58.
    const Toggle =({DOM}) => ({DOM:...}); const main = ({DOM}) => {
 const toggleOlives = Toggle({DOM: DOM.select('.olives')});
 const toggleMushrooms = Toggle({DOM}); const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM, (toggleOlives, toggleMushrooms) =>
 div([
 toggleOlives,
 toggleMushrooms
 ])
 ); return {
 DOM: view$
 }
 };
  • 59.
    const Toggle =({DOM}) => ({DOM:...}); const main = ({DOM}) => {
 const toggleOlives = Toggle({DOM: DOM.select('.olives')});
 const toggleMushrooms = Toggle({DOM}); const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM, (toggleOlives, toggleMushrooms) =>
 div([
 div('.olives', [toggleOlives]),
 toggleMushrooms
 ])
 ); return {
 DOM: view$
 }
 };
  • 60.
    const Toggle =({DOM}) => ({DOM:...}); const main = ({DOM}) => {
 const toggleOlives = Toggle({DOM: DOM.select(‘.olives')}); const toggleMushrooms = Toggle({DOM: DOM.select('.mushrooms')});
 const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM,
 (toggleOlives, toggleMushrooms) =>
 div([
 div('.olives', [toggleOlives]),
 div('.mushrooms', [toggleMushrooms])
 ])
 );
 return {
 DOM: view$
 }
 };
  • 61.
  • 62.
    const props$ =$.of({
 name: 'Pineapple'
 })
  • 63.
    const props$ =$.of({
 name: 'Pineapple'
 })
  • 64.
    const Toggle =({DOM, }) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked).startWith(false);
 const view$ = $.combineLatest(model$,
 (toggled, ) =>
 div([input({type: 'checkbox'}),
 ,
 p(toggled ? 'ON' : 'off')]));
 return {
 DOM: view$, 
 
 }
 }; const props$ = $.of({
 name: 'Pineapple'
 })
  • 65.
    const Toggle =({DOM, props$}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked).startWith(false);
 const view$ = $.combineLatest(model$, 
 (toggled, ) =>
 div([input({type: 'checkbox'}),
 ,
 p(toggled ? 'ON' : 'off')]));
 return {
 DOM: view$, 
 
 }
 }; const props$ = $.of({
 name: 'Pineapple'
 })
  • 66.
    const Toggle =({DOM, props$}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked).startWith(false);
 const view$ = $.combineLatest(model$, props$,
 (toggled, ) =>
 div([input({type: 'checkbox'}),
 ,
 p(toggled ? 'ON' : 'off')]));
 return {
 DOM: view$, 
 
 }
 }; const props$ = $.of({
 name: 'Pineapple'
 })
  • 67.
    const Toggle =({DOM, props$}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked).startWith(false);
 const view$ = $.combineLatest(model$, props$,
 (toggled, props) =>
 div([input({type: 'checkbox'}),
 ,
 p(toggled ? 'ON' : 'off')]));
 return {
 DOM: view$, 
 
 }
 }; const props$ = $.of({
 name: 'Pineapple'
 })
  • 68.
    const Toggle =({DOM, props$}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked).startWith(false);
 const view$ = $.combineLatest(model$, props$,
 (toggled, props) =>
 div([input({type: 'checkbox'}),
 props.name,
 p(toggled ? 'ON' : 'off')]));
 return {
 DOM: view$, 
 
 }
 }; const props$ = $.of({
 name: 'Pineapple'
 })
  • 69.
    const Toggle =({DOM, props$}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked).startWith(false);
 const view$ = $.combineLatest(model$, props$,
 (toggled, props) =>
 div([input({type: 'checkbox'}),
 props.name,
 p(toggled ? 'ON' : 'off')]));
 return {
 DOM: view$, 
 value$: model$ }
 }; const props$ = $.of({
 name: 'Pineapple'
 })
  • 70.
    const Toggle =({DOM, props$}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked).startWith(false);
 const view$ = $.combineLatest(model$, props$,
 (toggled, props) =>
 div([input({type: 'checkbox'}),
 props.name,
 p(toggled ? 'ON' : 'off')]));
 return {
 DOM: view$, 
 value$: model$ }
 }; const props$ = $.of({
 name: 'Pineapple'
 }) toggleOlives.value$.map(...)
  • 71.
    Next • More Drivers:HTTP, Storage, React Native • HTML to hyperscript • cyc - Generator • awesome-cyclers: Lots of info
  • 72.
  • 73.