SlideShare a Scribd company logo
Getting Reactive with
Cycle.js and XStream
TechExeter2017
Steve Lee
steve@opendirective.com
@SteveALee
Three things
• What is Reactive Programming with Streams
and Cycle.js.
• Why I should I care?
• How can I get started?
What we’ll cover
• Reactive programming with streams
• Cycle.js
• A little Functional Programming
• Some ES6+ Javascript syntax
• Virtual DOM and/or JSX
What is Reactive Programming?
• Reactive programming is programming with
asynchronous data streams – Andre Staltz
What is a Stream?
Observable and Observer
Observable Observer
Nothing New
• Event busses, queues, handlers…
• Microsoft Rx Extensions about 5 yrs old
• Netflix use Rx for their apps
• Angular provides Rx as an option
Let’s Start from the Top
What is Cycle.js
• Tiny amount of code
• Small set of general principles
• “A unified theory of everything, but for
JavaScript.” - @Widdershin
• It’s streams all the way down
If in doubt…
Principles
• Event loop between App and external world
• I/O Side effects separate from application logic
• No global state – data flows & reducers
Composable
Bonuses
• Explicit asynchronous dataflow
• Extensible by adding new drivers
• Relatively easy to test
Show me some Code!
https://jsbin.com/tewiwal/edit?js,output
HTML
// Placeholder element
<body>
<div id="app"></div>
</body>
Import Dependencies
// ES6 imports via Babel or TypeScript
// or global script with NPM CDN
const xs = … xstream
const Cycle = … cycle.js
const makeDOMDriver = … @cycle/DOM
Cycle.js Entry Function
// The Cycle.js framework API!
Cycle.run(Toggle, {
DOM: makeDOMDriver('#app')
});
Main Componet
// Toggle is our main component - App
Cycle.run(Toggle, {
DOM: makeDOMDriver('#app')
});
Collection of Drivers
Cycle.run(Toggle, {
DOM: makeDOMDriver('#app')
});
Drivers
• Just functions
• Output one of component sources
– DOM event Stream selector
• Input is a sink stream from the component
– VDOM updates – becomes the DOM
• Cycle connects based on Driver name
v
DOM Events
VDOM Updates
A Cycle.js Component
function Toggle(sources) {
const sinks = {
DOM: …};
return sinks;
}
A Cycle.js Component
// Passed sources, one per driver
// Returns Sinks, one per useful output stream
function Toggle((sources) {
const sinks = {
DOM: /* VDOM update stream */
};
return sinks;
}
The Complete Component
function Toggle(sources) {
const sinks = {
DOM: sources.DOM
.select('input').events('change')
.map(ev => ev.target.checked)
.startWith(false)
.map(toggled =>
div([
input({attrs: {type: 'checkbox'}}), 'Toggle me',
p(`${toggled ? 'ON' : 'off'}`)
])
)
};
return sinks;
}
Model View Intent
Component with MVI
function Toggle({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({attrs: {type: 'checkbox'}}), 'Toggle me',
p(`${toggled ? 'ON' : 'off'}`)
])
)
sinks = { DOM: view$ }
return sinks
}
Object Destructuring
Given
const sources = { DOM: … }
Then
const DOM = sources.DOM
Can be written as
const {DOM} = sources
foo({DOM})
User Intent
function Toggle({DOM}) {
const intent$ = DOM.select('input').events('change’)
…
return sinks
}
DOM Driver events
• All input events come in through sources
• Driver lets you use CSS selectors
• Composition requires event “isolation”
Model
// state is true or false, initially false
function Toggle({DOM}) {
…
const model$ = intent$.map(ev => ev.target.checked)
.startWith(false)
…
return sinks
}
ES6 Fat Arrow Functions
const mapper = ev => ev.target.checked
Somewhat equivalent to
Function mapper(ev){
return ev.target.checked
}
• Expression
• Shortcut syntax
• No “wtf is this” problems
View
// Return a stream of VDOM Nodes
function Toggle({DOM}) {
…
const view$ = model$.map(toggled =>
div([
input({attrs: {type: 'checkbox'}}), 'Toggle me',
p(`${toggled ? 'ON' : 'off'}`)
])
)
sinks = { DOM: view$ }
return sinks
}
Virtual DOM
• DOM updates are slow
• Virtual DOM looks like DOM but is faster
• Manages when to update DOM and what
• Practical to define view based on state
• React made Virtual DOMs popular
• Cycle uses one called snabbdom
Snabbdom
// Hyperscript helper functions. Can also use JSX
div([
input({attrs: {type: 'checkbox'}}), 'Toggle me',
p(`${toggled ? 'ON' : 'off'}`)
])
Is rendered as this HTML
<div>
<input type="checkbox">Toggle me
<p>off</p>
</input>
</div>
ES6 Template string
// backtick allows embedded expressions
const string = `${toggled ? 'ON' : 'off'}`
Stream view
// Select a stream of DOM events
sources.DOM.select('input').events('change’)
// Converts each event to checked state
.map(ev => ev.target.checked)
// Initial state is false
.startWith(false)
// Convert state to VDOM update
.map(toggled =>
div([
input({attrs: {type: 'checkbox'}}), 'Toggle me',
p(`${toggled ? 'ON' : 'off'}`)
])
)
Streams
• Explicit flow of ‘events’
• From Sources (producer) to sinks (consumer)
• Through a sequence of simple operators
Declarative
• The stream operators say what happens
• Not how – eg no imperative loops
• Uses functional style operators on streams
– Eg map, reduce (aka fold), filter ….
– Similar to array extras, but over time not in
memory
– Stream specific operators like “merge”
Marble Diagram
http://rxmarbles.com/
Immutable
• Operators return new streams
• Pure functions – no surprises
• No modification of global state
State handling
• Follow events
• Fold() modifies ‘state’ over a series of events
• Onionify provide single state tree cf. Redux
– Layered to match composition structure
– State input to component as a Stream
– Changes in state returned as reducer functions
– Persist to browser storage
• Roll your own
Summary
• Component is functional stream code
– no side effects, immutable, pure
• Side effects in the drivers
• Intent selected events from the DOM driver
• Intent maps to model state
• Model maps to view stream of VNodes
• VNodes returned to driver for rendering
v
DOM Events
VDOM Updates
What about those Observables?
• Cycle keeps them in drivers
• Interface between streams and side effects
• Keeps ‘external’ imperative logic out of main
• Uses xstream library rather then RxJS
– Always hot
Observable pattern
• Separates producer and consumer
• Streams between observable and observer
• Pub Sub
• Push
• GoF “Observer” plus “Iterable” patterns
• ECMAScript TC39 Stage 1 proposal
// Adds a listener (Observer) to the input stream
Function logDriver(msg$){
msg$.addListener({
next: msg => console.log(msg)
})
/* no source */
}
A Write-only Driver
// Pushes message to stream when a websocket message arrives
function WSDriver(/* no sinks */) {
return xs.create({
start: listener => {
this.connection = new WebSocket('ws://localhost:4000’);
connection.onmessage = (msg) => {
listener.next(msg)
}
});
}
A Read-only Driver
Learning Curve - Brain rewire
• Seems weird if only used to Classical OOP
• New idioms and traps to learn
• Different method of state handling
• Much easier than just using streams
• ES6+ Fat Arrows, Destructuring, Rest/Spread
Why bother
• Explicitly handles async complexity
– Simpler than long promise chains
• Cleaner declarative code
• Functional code predicability
• Pure code is easier to test - no mocking
• You might like it
• Matches “Event driven” serverless
Why Not?
• Effort to internalise new concepts
• Is young and still being refined
• Debugging can be tricky as lack of tools
– Often effectively log to console
• Finding developers may be hard
– FP is sadly not as familiar as it could be
• Community is small – also good
How can I start?
• CreateCycleApp and One Fits All flavor
• Cycle.js docs and samples
• Staltz’s “The introduction to Reactive
Programming you've been missing”
• Staltz’s egghead.io courses
• Helpful community on GitHub and gitter
Questions?
@SteveALee
steve@opendirective.com

More Related Content

What's hot

Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016
Ben Lesh
 
XQuery in the Cloud
XQuery in the CloudXQuery in the Cloud
XQuery in the Cloud
William Candillon
 
동기화 시대를 뛰어넘는 비동기 프로그래밍
동기화 시대를 뛰어넘는 비동기 프로그래밍동기화 시대를 뛰어넘는 비동기 프로그래밍
동기화 시대를 뛰어넘는 비동기 프로그래밍
명신 김
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJava
Rick Warren
 
High Performance Core Data
High Performance Core DataHigh Performance Core Data
High Performance Core Data
Matthew Morey
 
Intro to node and mongodb 1
Intro to node and mongodb   1Intro to node and mongodb   1
Intro to node and mongodb 1Mohammad Qureshi
 
Cutting Edge Data Processing with PHP & XQuery
Cutting Edge Data Processing with PHP & XQueryCutting Edge Data Processing with PHP & XQuery
Cutting Edge Data Processing with PHP & XQuery
William Candillon
 
Adventures in Multithreaded Core Data
Adventures in Multithreaded Core DataAdventures in Multithreaded Core Data
Adventures in Multithreaded Core DataInferis
 
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby DeveloperVenturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Jon Kruger
 
Reactive Thinking in Java
Reactive Thinking in JavaReactive Thinking in Java
Reactive Thinking in Java
Yakov Fain
 
Reactive Access to MongoDB from Scala
Reactive Access to MongoDB from ScalaReactive Access to MongoDB from Scala
Reactive Access to MongoDB from Scala
Hermann Hueck
 
Node.js: Continuation-Local-Storage and the Magic of AsyncListener
Node.js: Continuation-Local-Storage and the Magic of AsyncListenerNode.js: Continuation-Local-Storage and the Magic of AsyncListener
Node.js: Continuation-Local-Storage and the Magic of AsyncListener
Islam Sharabash
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsLeonardo Borges
 
Core Data with multiple managed object contexts
Core Data with multiple managed object contextsCore Data with multiple managed object contexts
Core Data with multiple managed object contexts
Matthew Morey
 
Simpler Core Data with RubyMotion
Simpler Core Data with RubyMotionSimpler Core Data with RubyMotion
Simpler Core Data with RubyMotion
Stefan Haflidason
 
Android architecture component - FbCircleDev Yogyakarta Indonesia
Android architecture component - FbCircleDev Yogyakarta IndonesiaAndroid architecture component - FbCircleDev Yogyakarta Indonesia
Android architecture component - FbCircleDev Yogyakarta Indonesia
Pratama Nur Wijaya
 
Reactive Design Patterns — J on the Beach
Reactive Design Patterns — J on the BeachReactive Design Patterns — J on the Beach
Reactive Design Patterns — J on the Beach
Roland Kuhn
 

What's hot (20)

Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016
 
XQuery in the Cloud
XQuery in the CloudXQuery in the Cloud
XQuery in the Cloud
 
동기화 시대를 뛰어넘는 비동기 프로그래밍
동기화 시대를 뛰어넘는 비동기 프로그래밍동기화 시대를 뛰어넘는 비동기 프로그래밍
동기화 시대를 뛰어넘는 비동기 프로그래밍
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJava
 
Not your Grandma's XQuery
Not your Grandma's XQueryNot your Grandma's XQuery
Not your Grandma's XQuery
 
High Performance Core Data
High Performance Core DataHigh Performance Core Data
High Performance Core Data
 
Intro to node and mongodb 1
Intro to node and mongodb   1Intro to node and mongodb   1
Intro to node and mongodb 1
 
JS Anti Patterns
JS Anti PatternsJS Anti Patterns
JS Anti Patterns
 
Cutting Edge Data Processing with PHP & XQuery
Cutting Edge Data Processing with PHP & XQueryCutting Edge Data Processing with PHP & XQuery
Cutting Edge Data Processing with PHP & XQuery
 
Adventures in Multithreaded Core Data
Adventures in Multithreaded Core DataAdventures in Multithreaded Core Data
Adventures in Multithreaded Core Data
 
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby DeveloperVenturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
Venturing Into The Wild: A .NET Developer's Experience As A Ruby Developer
 
Nio
NioNio
Nio
 
Reactive Thinking in Java
Reactive Thinking in JavaReactive Thinking in Java
Reactive Thinking in Java
 
Reactive Access to MongoDB from Scala
Reactive Access to MongoDB from ScalaReactive Access to MongoDB from Scala
Reactive Access to MongoDB from Scala
 
Node.js: Continuation-Local-Storage and the Magic of AsyncListener
Node.js: Continuation-Local-Storage and the Magic of AsyncListenerNode.js: Continuation-Local-Storage and the Magic of AsyncListener
Node.js: Continuation-Local-Storage and the Magic of AsyncListener
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event Systems
 
Core Data with multiple managed object contexts
Core Data with multiple managed object contextsCore Data with multiple managed object contexts
Core Data with multiple managed object contexts
 
Simpler Core Data with RubyMotion
Simpler Core Data with RubyMotionSimpler Core Data with RubyMotion
Simpler Core Data with RubyMotion
 
Android architecture component - FbCircleDev Yogyakarta Indonesia
Android architecture component - FbCircleDev Yogyakarta IndonesiaAndroid architecture component - FbCircleDev Yogyakarta Indonesia
Android architecture component - FbCircleDev Yogyakarta Indonesia
 
Reactive Design Patterns — J on the Beach
Reactive Design Patterns — J on the BeachReactive Design Patterns — J on the Beach
Reactive Design Patterns — J on the Beach
 

Similar to Getting Reactive with Cycle.js and xstream

Getting Reactive with CycleJS and XStream
Getting Reactive with CycleJS and XStream Getting Reactive with CycleJS and XStream
Getting Reactive with CycleJS and XStream
TechExeter
 
Spring Web Services: SOAP vs. REST
Spring Web Services: SOAP vs. RESTSpring Web Services: SOAP vs. REST
Spring Web Services: SOAP vs. REST
Sam Brannen
 
Top 10 RxJs Operators in Angular
Top 10 RxJs Operators in Angular Top 10 RxJs Operators in Angular
Top 10 RxJs Operators in Angular
Jalpesh Vadgama
 
Continuous Application with Structured Streaming 2.0
Continuous Application with Structured Streaming 2.0Continuous Application with Structured Streaming 2.0
Continuous Application with Structured Streaming 2.0
Anyscale
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
pootsbook
 
Serverless Java on Kubernetes
Serverless Java on KubernetesServerless Java on Kubernetes
Serverless Java on Kubernetes
Krzysztof Sobkowiak
 
Introduction to REST API with Node.js
Introduction to REST API with Node.jsIntroduction to REST API with Node.js
Introduction to REST API with Node.js
Yoann Gotthilf
 
540slidesofnodejsbackendhopeitworkforu.pdf
540slidesofnodejsbackendhopeitworkforu.pdf540slidesofnodejsbackendhopeitworkforu.pdf
540slidesofnodejsbackendhopeitworkforu.pdf
hamzadamani7
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applicationsTom Croucher
 
REACT.JS : Rethinking UI Development Using JavaScript
REACT.JS : Rethinking UI Development Using JavaScriptREACT.JS : Rethinking UI Development Using JavaScript
REACT.JS : Rethinking UI Development Using JavaScript
Deepu S Nath
 
Scalable io in java
Scalable io in javaScalable io in java
Scalable io in java
Giridhar Addepalli
 
The State of JavaScript (2015)
The State of JavaScript (2015)The State of JavaScript (2015)
The State of JavaScript (2015)
Domenic Denicola
 
Using React, Redux and Saga with Lottoland APIs
Using React, Redux and Saga with Lottoland APIsUsing React, Redux and Saga with Lottoland APIs
Using React, Redux and Saga with Lottoland APIs
Mihail Gaberov
 
Zend server 6 using zf2, 2013 webinar
Zend server 6 using zf2, 2013 webinarZend server 6 using zf2, 2013 webinar
Zend server 6 using zf2, 2013 webinar
Yonni Mendes
 
Event-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineEvent-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 Engine
Ricardo Silva
 
CQRS / ES & DDD Demystified
CQRS / ES & DDD DemystifiedCQRS / ES & DDD Demystified
CQRS / ES & DDD Demystified
Vic Metcalfe
 
Intro to Sail.js
Intro to Sail.jsIntro to Sail.js
Intro to Sail.js
Nicholas McClay
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applications
Jeff Durta
 
Introduction to Vert.x
Introduction to Vert.xIntroduction to Vert.x
Introduction to Vert.x
Yiguang Hu
 
Hazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMSHazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMS
uzquiano
 

Similar to Getting Reactive with Cycle.js and xstream (20)

Getting Reactive with CycleJS and XStream
Getting Reactive with CycleJS and XStream Getting Reactive with CycleJS and XStream
Getting Reactive with CycleJS and XStream
 
Spring Web Services: SOAP vs. REST
Spring Web Services: SOAP vs. RESTSpring Web Services: SOAP vs. REST
Spring Web Services: SOAP vs. REST
 
Top 10 RxJs Operators in Angular
Top 10 RxJs Operators in Angular Top 10 RxJs Operators in Angular
Top 10 RxJs Operators in Angular
 
Continuous Application with Structured Streaming 2.0
Continuous Application with Structured Streaming 2.0Continuous Application with Structured Streaming 2.0
Continuous Application with Structured Streaming 2.0
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
 
Serverless Java on Kubernetes
Serverless Java on KubernetesServerless Java on Kubernetes
Serverless Java on Kubernetes
 
Introduction to REST API with Node.js
Introduction to REST API with Node.jsIntroduction to REST API with Node.js
Introduction to REST API with Node.js
 
540slidesofnodejsbackendhopeitworkforu.pdf
540slidesofnodejsbackendhopeitworkforu.pdf540slidesofnodejsbackendhopeitworkforu.pdf
540slidesofnodejsbackendhopeitworkforu.pdf
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
REACT.JS : Rethinking UI Development Using JavaScript
REACT.JS : Rethinking UI Development Using JavaScriptREACT.JS : Rethinking UI Development Using JavaScript
REACT.JS : Rethinking UI Development Using JavaScript
 
Scalable io in java
Scalable io in javaScalable io in java
Scalable io in java
 
The State of JavaScript (2015)
The State of JavaScript (2015)The State of JavaScript (2015)
The State of JavaScript (2015)
 
Using React, Redux and Saga with Lottoland APIs
Using React, Redux and Saga with Lottoland APIsUsing React, Redux and Saga with Lottoland APIs
Using React, Redux and Saga with Lottoland APIs
 
Zend server 6 using zf2, 2013 webinar
Zend server 6 using zf2, 2013 webinarZend server 6 using zf2, 2013 webinar
Zend server 6 using zf2, 2013 webinar
 
Event-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineEvent-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 Engine
 
CQRS / ES & DDD Demystified
CQRS / ES & DDD DemystifiedCQRS / ES & DDD Demystified
CQRS / ES & DDD Demystified
 
Intro to Sail.js
Intro to Sail.jsIntro to Sail.js
Intro to Sail.js
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applications
 
Introduction to Vert.x
Introduction to Vert.xIntroduction to Vert.x
Introduction to Vert.x
 
Hazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMSHazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMS
 

More from Steve Lee

2017-09-15 T4I Maavis, son on Brian is Always in Mind
2017-09-15 T4I Maavis, son on Brian is Always in Mind2017-09-15 T4I Maavis, son on Brian is Always in Mind
2017-09-15 T4I Maavis, son on Brian is Always in Mind
Steve Lee
 
2017 09-14 AAATE SteppingStones
2017 09-14 AAATE SteppingStones2017 09-14 AAATE SteppingStones
2017 09-14 AAATE SteppingStones
Steve Lee
 
2016 11-28 t4-i_steppingstones
2016 11-28 t4-i_steppingstones2016 11-28 t4-i_steppingstones
2016 11-28 t4-i_steppingstones
Steve Lee
 
2016-08-25 TechExeter - going serverless with Azure
2016-08-25 TechExeter - going serverless with Azure2016-08-25 TechExeter - going serverless with Azure
2016-08-25 TechExeter - going serverless with Azure
Steve Lee
 
Cycling for noobs
Cycling for noobsCycling for noobs
Cycling for noobs
Steve Lee
 
Module 2-web-a11y-steve lee
Module 2-web-a11y-steve leeModule 2-web-a11y-steve lee
Module 2-web-a11y-steve lee
Steve Lee
 
10 min intro to web a11y
10 min intro to web a11y10 min intro to web a11y
10 min intro to web a11ySteve Lee
 
TS11 Community anti-patterns
TS11 Community anti-patternsTS11 Community anti-patterns
TS11 Community anti-patterns
Steve Lee
 
Open accessibility – why is ‘open’ good for web accessibility?
Open accessibility – why is ‘open’ good for web accessibility?Open accessibility – why is ‘open’ good for web accessibility?
Open accessibility – why is ‘open’ good for web accessibility?
Steve Lee
 
Mobile a11y stack
Mobile a11y stackMobile a11y stack
Mobile a11y stack
Steve Lee
 

More from Steve Lee (10)

2017-09-15 T4I Maavis, son on Brian is Always in Mind
2017-09-15 T4I Maavis, son on Brian is Always in Mind2017-09-15 T4I Maavis, son on Brian is Always in Mind
2017-09-15 T4I Maavis, son on Brian is Always in Mind
 
2017 09-14 AAATE SteppingStones
2017 09-14 AAATE SteppingStones2017 09-14 AAATE SteppingStones
2017 09-14 AAATE SteppingStones
 
2016 11-28 t4-i_steppingstones
2016 11-28 t4-i_steppingstones2016 11-28 t4-i_steppingstones
2016 11-28 t4-i_steppingstones
 
2016-08-25 TechExeter - going serverless with Azure
2016-08-25 TechExeter - going serverless with Azure2016-08-25 TechExeter - going serverless with Azure
2016-08-25 TechExeter - going serverless with Azure
 
Cycling for noobs
Cycling for noobsCycling for noobs
Cycling for noobs
 
Module 2-web-a11y-steve lee
Module 2-web-a11y-steve leeModule 2-web-a11y-steve lee
Module 2-web-a11y-steve lee
 
10 min intro to web a11y
10 min intro to web a11y10 min intro to web a11y
10 min intro to web a11y
 
TS11 Community anti-patterns
TS11 Community anti-patternsTS11 Community anti-patterns
TS11 Community anti-patterns
 
Open accessibility – why is ‘open’ good for web accessibility?
Open accessibility – why is ‘open’ good for web accessibility?Open accessibility – why is ‘open’ good for web accessibility?
Open accessibility – why is ‘open’ good for web accessibility?
 
Mobile a11y stack
Mobile a11y stackMobile a11y stack
Mobile a11y stack
 

Recently uploaded

Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
rickgrimesss22
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
Shane Coughlan
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
Boni García
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Mind IT Systems
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
NYGGS Automation Suite
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
Fermin Galan
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Crescat
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
Aftab Hussain
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
timtebeek1
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
Deuglo Infosystem Pvt Ltd
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
Łukasz Chruściel
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
Max Andersen
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 
Pro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp BookPro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp Book
abdulrafaychaudhry
 
E-commerce Application Development Company.pdf
E-commerce Application Development Company.pdfE-commerce Application Development Company.pdf
E-commerce Application Development Company.pdf
Hornet Dynamics
 
AI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website CreatorAI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website Creator
Google
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
Google
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
Paco van Beckhoven
 
Enhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdfEnhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdf
Globus
 

Recently uploaded (20)

Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 
Pro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp BookPro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp Book
 
E-commerce Application Development Company.pdf
E-commerce Application Development Company.pdfE-commerce Application Development Company.pdf
E-commerce Application Development Company.pdf
 
AI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website CreatorAI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website Creator
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
 
Enhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdfEnhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdf
 

Getting Reactive with Cycle.js and xstream

  • 1. Getting Reactive with Cycle.js and XStream TechExeter2017 Steve Lee steve@opendirective.com @SteveALee
  • 2. Three things • What is Reactive Programming with Streams and Cycle.js. • Why I should I care? • How can I get started?
  • 3. What we’ll cover • Reactive programming with streams • Cycle.js • A little Functional Programming • Some ES6+ Javascript syntax • Virtual DOM and/or JSX
  • 4. What is Reactive Programming? • Reactive programming is programming with asynchronous data streams – Andre Staltz
  • 5. What is a Stream?
  • 7. Nothing New • Event busses, queues, handlers… • Microsoft Rx Extensions about 5 yrs old • Netflix use Rx for their apps • Angular provides Rx as an option
  • 9.
  • 10. What is Cycle.js • Tiny amount of code • Small set of general principles • “A unified theory of everything, but for JavaScript.” - @Widdershin • It’s streams all the way down
  • 12. Principles • Event loop between App and external world • I/O Side effects separate from application logic • No global state – data flows & reducers
  • 13.
  • 15.
  • 16. Bonuses • Explicit asynchronous dataflow • Extensible by adding new drivers • Relatively easy to test
  • 17. Show me some Code! https://jsbin.com/tewiwal/edit?js,output
  • 18. HTML // Placeholder element <body> <div id="app"></div> </body>
  • 19. Import Dependencies // ES6 imports via Babel or TypeScript // or global script with NPM CDN const xs = … xstream const Cycle = … cycle.js const makeDOMDriver = … @cycle/DOM
  • 20. Cycle.js Entry Function // The Cycle.js framework API! Cycle.run(Toggle, { DOM: makeDOMDriver('#app') });
  • 21. Main Componet // Toggle is our main component - App Cycle.run(Toggle, { DOM: makeDOMDriver('#app') });
  • 22. Collection of Drivers Cycle.run(Toggle, { DOM: makeDOMDriver('#app') });
  • 23. Drivers • Just functions • Output one of component sources – DOM event Stream selector • Input is a sink stream from the component – VDOM updates – becomes the DOM • Cycle connects based on Driver name
  • 25. A Cycle.js Component function Toggle(sources) { const sinks = { DOM: …}; return sinks; }
  • 26. A Cycle.js Component // Passed sources, one per driver // Returns Sinks, one per useful output stream function Toggle((sources) { const sinks = { DOM: /* VDOM update stream */ }; return sinks; }
  • 27. The Complete Component function Toggle(sources) { const sinks = { DOM: sources.DOM .select('input').events('change') .map(ev => ev.target.checked) .startWith(false) .map(toggled => div([ input({attrs: {type: 'checkbox'}}), 'Toggle me', p(`${toggled ? 'ON' : 'off'}`) ]) ) }; return sinks; }
  • 29. Component with MVI function Toggle({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({attrs: {type: 'checkbox'}}), 'Toggle me', p(`${toggled ? 'ON' : 'off'}`) ]) ) sinks = { DOM: view$ } return sinks }
  • 30. Object Destructuring Given const sources = { DOM: … } Then const DOM = sources.DOM Can be written as const {DOM} = sources foo({DOM})
  • 31. User Intent function Toggle({DOM}) { const intent$ = DOM.select('input').events('change’) … return sinks }
  • 32. DOM Driver events • All input events come in through sources • Driver lets you use CSS selectors • Composition requires event “isolation”
  • 33. Model // state is true or false, initially false function Toggle({DOM}) { … const model$ = intent$.map(ev => ev.target.checked) .startWith(false) … return sinks }
  • 34. ES6 Fat Arrow Functions const mapper = ev => ev.target.checked Somewhat equivalent to Function mapper(ev){ return ev.target.checked } • Expression • Shortcut syntax • No “wtf is this” problems
  • 35. View // Return a stream of VDOM Nodes function Toggle({DOM}) { … const view$ = model$.map(toggled => div([ input({attrs: {type: 'checkbox'}}), 'Toggle me', p(`${toggled ? 'ON' : 'off'}`) ]) ) sinks = { DOM: view$ } return sinks }
  • 36. Virtual DOM • DOM updates are slow • Virtual DOM looks like DOM but is faster • Manages when to update DOM and what • Practical to define view based on state • React made Virtual DOMs popular • Cycle uses one called snabbdom
  • 37. Snabbdom // Hyperscript helper functions. Can also use JSX div([ input({attrs: {type: 'checkbox'}}), 'Toggle me', p(`${toggled ? 'ON' : 'off'}`) ]) Is rendered as this HTML <div> <input type="checkbox">Toggle me <p>off</p> </input> </div>
  • 38. ES6 Template string // backtick allows embedded expressions const string = `${toggled ? 'ON' : 'off'}`
  • 39. Stream view // Select a stream of DOM events sources.DOM.select('input').events('change’) // Converts each event to checked state .map(ev => ev.target.checked) // Initial state is false .startWith(false) // Convert state to VDOM update .map(toggled => div([ input({attrs: {type: 'checkbox'}}), 'Toggle me', p(`${toggled ? 'ON' : 'off'}`) ]) )
  • 40. Streams • Explicit flow of ‘events’ • From Sources (producer) to sinks (consumer) • Through a sequence of simple operators
  • 41. Declarative • The stream operators say what happens • Not how – eg no imperative loops • Uses functional style operators on streams – Eg map, reduce (aka fold), filter …. – Similar to array extras, but over time not in memory – Stream specific operators like “merge”
  • 43. Immutable • Operators return new streams • Pure functions – no surprises • No modification of global state
  • 44. State handling • Follow events • Fold() modifies ‘state’ over a series of events • Onionify provide single state tree cf. Redux – Layered to match composition structure – State input to component as a Stream – Changes in state returned as reducer functions – Persist to browser storage • Roll your own
  • 45. Summary • Component is functional stream code – no side effects, immutable, pure • Side effects in the drivers • Intent selected events from the DOM driver • Intent maps to model state • Model maps to view stream of VNodes • VNodes returned to driver for rendering
  • 47. What about those Observables? • Cycle keeps them in drivers • Interface between streams and side effects • Keeps ‘external’ imperative logic out of main • Uses xstream library rather then RxJS – Always hot
  • 48. Observable pattern • Separates producer and consumer • Streams between observable and observer • Pub Sub • Push • GoF “Observer” plus “Iterable” patterns • ECMAScript TC39 Stage 1 proposal
  • 49. // Adds a listener (Observer) to the input stream Function logDriver(msg$){ msg$.addListener({ next: msg => console.log(msg) }) /* no source */ } A Write-only Driver
  • 50. // Pushes message to stream when a websocket message arrives function WSDriver(/* no sinks */) { return xs.create({ start: listener => { this.connection = new WebSocket('ws://localhost:4000’); connection.onmessage = (msg) => { listener.next(msg) } }); } A Read-only Driver
  • 51. Learning Curve - Brain rewire • Seems weird if only used to Classical OOP • New idioms and traps to learn • Different method of state handling • Much easier than just using streams • ES6+ Fat Arrows, Destructuring, Rest/Spread
  • 52. Why bother • Explicitly handles async complexity – Simpler than long promise chains • Cleaner declarative code • Functional code predicability • Pure code is easier to test - no mocking • You might like it • Matches “Event driven” serverless
  • 53. Why Not? • Effort to internalise new concepts • Is young and still being refined • Debugging can be tricky as lack of tools – Often effectively log to console • Finding developers may be hard – FP is sadly not as familiar as it could be • Community is small – also good
  • 54. How can I start? • CreateCycleApp and One Fits All flavor • Cycle.js docs and samples • Staltz’s “The introduction to Reactive Programming you've been missing” • Staltz’s egghead.io courses • Helpful community on GitHub and gitter

Editor's Notes

  1. OpenDirective = Rgardler + myself
  2. No inheritance  Your App is just a component like others
  3. Streams!
  4. Streams!