1 of 33

Watup, could you pick up this thing for me NEARBY?

2 of 33

HOME

NEARBY

After 20 metres

After 10 metres

After 5 metres

Destination

3 of 33

HOME

NEARBY

After 20 metres

After 10 metres

After 5 metres

Destination

4 of 33

You have to check out this RESTAURANT on your trip abroad!

5 of 33

HOTEL

RESTAURANT

After 20 metres

After 10 metres

After 100 metres

After 28 metres

After 5 metres

After 50 metres

After 23 metres

After 5 metres

After 10 metres

After 20 metres

6 of 33

HOTEL

RESTAURANT

After 20 metres

After 10 metres

After 100 metres

After 28 metres

After 5 metres

After 50 metres

After 23 metres

After 5 metres

After 10 metres

After 20 metres

7 of 33

HOTEL

RESTAURANT

After 20 metres

After 10 metres

After 100 metres

After 28 metres

After 5 metres

After 50 metres

After 23 metres

After 5 metres

After 10 metres

After 20 metres

IMPERATIVE

DECLARATIVE

8 of 33

Declarative state and side effects management for popular JavaScript frameworks

Cerebral

9 of 33

Stateful Component method

Mobx Action

Redux Thunk/Reducer

Cerebral Signal

APPLICATION LOGIC

10 of 33

11 of 33

webpackbin - 2016

collaboration - 2017

12 of 33

DEBUGGER

CODE

PROJECT

13 of 33

http://localhost

CODE EDITOR

BROWSER

COMPANION

14 of 33

3 files

store/sequences.js

store/actions.js

store/factories.js

10 files

pages/index.js

store/connection/actions.js

store/connection/reducer.js

store/user/actions.js

store/user/reducer.js

store/api/actions.js

pages/Sandbox/index.js

store/entities/sandboxes/actions/index.js

store/entities/sandboxes/reducer.js

store/entities/sandboxes/entity.js

21 state changes

9 side effects

sandboxChanged

15 of 33

export const loadSandbox = factories.withLoadApp([

set(state`editor.error`, null),

when(state`editor.sandboxes.${props`id`}`),

{

true: [

set(state`editor.currentId`, props`id`),

set(props`sandbox`, state`editor.sandboxes.${props`id`}`),

actions.setCurrentModuleShortid,

actions.setMainModuleShortid,

actions.setInitialTab,

actions.setUrlOptions,

actions.setWorkspace,

],

false: [

set(state`editor.isLoading`, true),

set(state`editor.notFound`, false),

set(state`editor.changedModuleShortids`, []),

actions.getSandbox,

{

success: [

set(state`editor.sandboxes.${props`sandbox.id`}`, props`sandbox`),

set(state`editor.currentId`, props`sandbox.id`),

actions.setCurrentModuleShortid,

actions.setMainModuleShortid,

actions.setInitialTab,

actions.setUrlOptions,

actions.setWorkspace,

ensurePackageJSON,

],

notFound: set(state`editor.notFound`, true),

error: set(state`editor.error`, props`error.message`),

},

],

},

set(state`editor.isLoading`, false),

]);

3 files

store/sequences.js

store/actions.js

store/factories.js

10 files

pages/index.js

store/connection/actions.js

store/connection/reducer.js

store/user/actions.js

store/user/reducer.js

store/api/actions.js

pages/Sandbox/index.js

store/entities/sandboxes/actions/index.js

store/entities/sandboxes/reducer.js

store/entities/sandboxes/entity.js

21 state changes

9 side effects

sandboxChanged

16 of 33

export const loadSandbox = withLoadApp([

set(state`editor.error`, null),

when(state`editor.sandboxes.${props`id`}`),

{

true: [

set(state`editor.currentId`, props`id`),

set(props`sandbox`, state`editor.sandboxes.${props`id`}`),

actions.setCurrentModuleShortid,

actions.setMainModuleShortid,

actions.setInitialTab,

actions.setUrlOptions,

actions.setWorkspace,

],

false: [

set(state`editor.isLoading`, true),

set(state`editor.notFound`, false),

set(state`editor.changedModuleShortids`, []),

actions.getSandbox,

{

success: [

set(state`editor.sandboxes.${props`sandbox.id`}`, props`sandbox`),

set(state`editor.currentId`, props`sandbox.id`),

actions.setCurrentModuleShortid,

actions.setMainModuleShortid,

actions.setInitialTab,

actions.setUrlOptions,

actions.setWorkspace,

ensurePackageJSON,

],

notFound: set(state`editor.notFound`, true),

error: set(state`editor.error`, props`error.message`),

},

],

},

set(state`editor.isLoading`, false),

]);

export const loadSandbox = withLoadApp([

...

]);

17 of 33

export const loadSandbox = withLoadApp([

set(state`editor.error`, null),

when(state`editor.sandboxes.${props`id`}`),

{

true: [

set(state`editor.currentId`, props`id`),

set(props`sandbox`, state`editor.sandboxes.${props`id`}`),

actions.setCurrentModuleShortid,

actions.setMainModuleShortid,

actions.setInitialTab,

actions.setUrlOptions,

actions.setWorkspace,

],

false: [

set(state`editor.isLoading`, true),

set(state`editor.notFound`, false),

set(state`editor.changedModuleShortids`, []),

actions.getSandbox,

{

success: [

set(state`editor.sandboxes.${props`sandbox.id`}`, props`sandbox`),

set(state`editor.currentId`, props`sandbox.id`),

actions.setCurrentModuleShortid,

actions.setMainModuleShortid,

actions.setInitialTab,

actions.setUrlOptions,

actions.setWorkspace,

ensurePackageJSON,

],

notFound: set(state`editor.notFound`, true),

error: set(state`editor.error`, props`error.message`),

},

],

},

set(state`editor.isLoading`, false),

]);

set(state`editor.error`, null),

18 of 33

export const loadSandbox = withLoadApp([

set(state`editor.error`, null),

when(state`editor.sandboxes.${props`id`}`),

{

true: [

set(state`editor.currentId`, props`id`),

set(props`sandbox`, state`editor.sandboxes.${props`id`}`),

actions.setCurrentModuleShortid,

actions.setMainModuleShortid,

actions.setInitialTab,

actions.setUrlOptions,

actions.setWorkspace,

],

false: [

set(state`editor.isLoading`, true),

set(state`editor.notFound`, false),

set(state`editor.changedModuleShortids`, []),

actions.getSandbox,

{

success: [

set(state`editor.sandboxes.${props`sandbox.id`}`, props`sandbox`),

set(state`editor.currentId`, props`sandbox.id`),

actions.setCurrentModuleShortid,

actions.setMainModuleShortid,

actions.setInitialTab,

actions.setUrlOptions,

actions.setWorkspace,

ensurePackageJSON,

],

notFound: set(state`editor.notFound`, true),

error: set(state`editor.error`, props`error.message`),

},

],

},

set(state`editor.isLoading`, false),

]);

when(state`editor.sandboxes.${props`id`}`),

{

true: [

...

],

false: [

...

],

},

19 of 33

export const loadSandbox = withLoadApp([

set(state`editor.error`, null),

when(state`editor.sandboxes.${props`id`}`),

{

true: [

set(state`editor.currentId`, props`id`),

set(props`sandbox`, state`editor.sandboxes.${props`id`}`),

actions.setCurrentModuleShortid,

actions.setMainModuleShortid,

actions.setInitialTab,

actions.setUrlOptions,

actions.setWorkspace,

],

false: [

set(state`editor.isLoading`, true),

set(state`editor.notFound`, false),

set(state`editor.changedModuleShortids`, []),

actions.getSandbox,

{

success: [

set(state`editor.sandboxes.${props`sandbox.id`}`, props`sandbox`),

set(state`editor.currentId`, props`sandbox.id`),

actions.setCurrentModuleShortid,

actions.setMainModuleShortid,

actions.setInitialTab,

actions.setUrlOptions,

actions.setWorkspace,

ensurePackageJSON,

],

notFound: set(state`editor.notFound`, true),

error: set(state`editor.error`, props`error.message`),

},

],

},

set(state`editor.isLoading`, false),

]);

set(state`editor.currentId`, props`id`),

set(props`sandbox`, state`editor.sandboxes.${props`id`}`),

actions.setCurrentModuleShortid,

actions.setMainModuleShortid,

actions.setInitialTab,

actions.setUrlOptions,

actions.setWorkspace,

20 of 33

export const loadSandbox = withLoadApp([

set(state`editor.error`, null),

when(state`editor.sandboxes.${props`id`}`),

{

true: [

set(state`editor.currentId`, props`id`),

set(props`sandbox`, state`editor.sandboxes.${props`id`}`),

actions.setCurrentModuleShortid,

actions.setMainModuleShortid,

actions.setInitialTab,

actions.setUrlOptions,

actions.setWorkspace,

],

false: [

set(state`editor.isLoading`, true),

set(state`editor.notFound`, false),

set(state`editor.changedModuleShortids`, []),

actions.getSandbox,

{

success: [

set(state`editor.sandboxes.${props`sandbox.id`}`, props`sandbox`),

set(state`editor.currentId`, props`sandbox.id`),

actions.setCurrentModuleShortid,

actions.setMainModuleShortid,

actions.setInitialTab,

actions.setUrlOptions,

actions.setWorkspace,

ensurePackageJSON,

],

notFound: set(state`editor.notFound`, true),

error: set(state`editor.error`, props`error.message`),

},

],

},

set(state`editor.isLoading`, false),

]);

actions.getSandbox,

{

success: [

...

],

notFound: set(state`editor.notFound`, true),

error: set(state`editor.error`, props`error.message`),

},

21 of 33

Lessons learned refactoring Codesandbox.io from Redux to Cerebral

https://medium.com/@christianalfoni/lessons-learned-refactoring-codesandbox-io-from-redux-to-cerebral-40e9a5646281

22 of 33

FACEBOOK FLUX

ACTION

STORE

DISPATCHER

VIEW

23 of 33

STORE

STORE

STORE

STORE

ACTION

DISPATCHER

VIEW

FACEBOOK FLUX

BAOBAB

VIEW

ELM

DB INSIDE OUT

24 of 33

tree.set([‘text’], ‘newText’)

{

method: ‘set’,

path: [‘text’],

value: ‘newText’

}

25 of 33

May 9th

2015

May 8th

2015

July 2nd

2015

Immutable-store gets signals and a time machine

Cerebral first commit

Live React: Hot Reloading with Time Travel at react-europe 2015

https://www.youtube.com/watch?v=Txpw4wU4BCU&t=127s

https://www.youtube.com/watch?v=xsSnOQynTHs

26 of 33

[

]

CEREBRAL

FUNCTION-TREE

ADDRESSBAR

https://localhost

27 of 33

67 CONTRIBUTORS

28 of 33

29 of 33

30 of 33

www.cerebraljs.com

31 of 33

32 of 33

tree.set([‘text’], ‘newText’)

{

method: ‘set’,

path: [‘text’],

value: ‘newText’

}

dispatch({� type: ‘UPDATE_TEXT’,

payload: ‘newText’�})

{� type: ‘UPDATE_TEXT’,

payload: ‘newText’�}

(state, action) => {

return newState

}

DISPATCH

TRANSACTION

MUTATION

TREE

33 of 33

tree.set([‘text’], ‘newText’)

{

method: ‘set’,

path: [‘text’],

value: ‘newText’

}

dispatch({� type: ‘UPDATE_TEXT’,

payload: ‘newText’�})

{� type: ‘UPDATE_TEXT’,

payload: ‘newText’�}

(state, action) => {

return newState

}

DISPATCH

TRANSACTION

MUTATION

TREE