@davidkpiano
📄
📄
📄
📄
Delete
Are you sure?
Yes
No
Delete
Undo
Deleted!
have one initial state
a finite number of states
a finite number of events
a mapping of state transitions
triggered by events
a finite number of final states
Sign in
Signing in...
Profile
Home
SUBMIT
SUCCESS
UNAUTHORIZED
PROFILE
How was your experience?
𝘅
Good
Bad
Tell us why?
𝘅
Submit
Thanks for your feedback.
𝘅
Close
import { Machine } from 'xstate';
const feedbackMachine = Machine({
id: 'feedback',
initial: 'question',
states: {
question: {
on: {
CLICK_GOOD: 'thanks',
CLICK_BAD: 'form',
CLOSE: 'closed',
ESC: 'closed'
}
},
form: {
on: {
SUBMIT: 'thanks',
CLOSE: 'closed',
ESC: 'closed'
}
},
thanks: {
on: {
CLOSE: 'closed',
ESC: 'closed'
}
},
closed: {
type: 'final'
}
}
});
import { feedbackMachine } from './feedbackMachine';
import { useMachine } from '@xstate/react';
const App = () => {
const [current, send] = useMachine(feedbackMachine);
return (
// ...
);
}
1. Abstract model
2. Transition analytics
3. Identify adaptive paths
4. Use analysis for adaptation
Photo by NEW DATA SERVICES on Unsplash
Success
Signing in
Error
0.9
0.1
How was your experience?
𝘅
Good
Bad
Tell us why?
𝘅
Submit
Thanks for your feedback.
𝘅
Close
Give Feedback
❓
❓
Login
Gallery
Profile
Camera
SUCCESS
TAP PROFILE
TAP CAMERA
BACK
BACK
Scroll
🗺 Login, Gallery, Gallery
🗺 Login, Gallery, Camera
🗺 Login, Gallery, Profile
0.90, 0.31
0.90, 0.57
0.90, 0.12
0.90
0.31
0.57
0.13
UNAUTHORIZED
0.10
SUCCESS
(decide)
TAP AD
+10
Gallery
Ads interspersed
Ads shown at top
Ad
Scroll
Scroll
TAP AD
+10
-1
-10
INTERSPERSED > .5
TOP > .5
Contextual data
New user?
< 30 days
>= 30 days
Show ad at top
Friend count?
< 100
>= 100
Show more ads
Show less ads
All data
A
B
C
D
E
A
B
C
D
E
import { Machine } from 'xstate';
const myMachine = Machine({
// ...
});
const myService = interpret(myMachine)
.onTransition(state => {
analytics.track({
target: state.value,
source: state.history
? state.history.value
: undefined,
event: sanitize(event),
timestamp: Date.now()
});
})
.start();
A
B
C
D
E
import { Machine } from 'xstate';
import { getShortestPaths } from '@xstate/graph';
const myMachine = Machine({
// ...
});
const shortestPaths = getShortestPaths(myMachine);
A: A
B: A -> B
C: A -> B -> C
D: A -> D
E: A -> D -> E
A
B
C
D
E
import { Machine } from 'xstate';
import { getShortestPaths } from '@xstate/graph';
const myMachine = Machine({
// ...
});
const shortestPaths = getShortestPaths(myMachine);
0.9
1.0
0.4
0.6
0.1
0.4
0.6
A: A
B: A -> D -> E -> B
C: A -> D -> E -> C
D: A -> D
E: A -> D -> E
A
B
C
0.75
0.25
D
E
(D) 1.00
(D) 0.00
A -> B A -> C A -> B A -> B
E -> D -> E -> F ->
Agent
Environment
Action
State
Reward
service.onTransition(state => {
analytics.track({
source: state.history.value,
target: state.value,
context: state.context,
event: state.event,
timestamp: Date.now()
})
});
Application
Executable Model
Metrics Tracking
Adaptive Transitions
Adaptive UI
xstate
@xstate/react
@xstate/graph
@xstate/vue
@xstate/test
@xstate/analytics
@xstate/sim
@xstate/viz
✅
✅
✅
🔜
🔜
🕐
🕐
🕐
@davidkpiano