-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathdocs-text.js
1 lines (1 loc) · 144 KB
/
docs-text.js
1
{"introduction":{"index":{"raw":"# Get started\n\n```marksy\n<Youtube url=\"https://www.youtube.com/embed/mYkM8CiVsXw\" />\n```\n\n## Install on my machine\n\n1. Install [Node](https://nodejs.org/en/), the JavaScript Runtime\n2. Create a project using a build tool like [Parcel JS](https://parceljs.org)\n3. Run `npm install cerebral`\n4. Install your view package of choice, for example: `npm install @cerebral/react`\n\n## Download debugger\n\n[Download the Debugger](https://github.com/cerebral/cerebral-debugger/releases) for your target OS:\n\n* **Mac**: cerebral-debugger-x.x.x.dmg\n* **Windows**: cerebral-debugger-setup-x.x.x.exe\n* **Linux**: cerebral-debugger_x.x.x_amd64.deb\n\nThe debugger will automatically notify you and self-update. On Linux auto-update works only for the [snap](https://snapcraft.io) package.\n","title":"Get started"},"the_architecture":{"raw":"# The architecture\n\n## Vision\n\nThe architecture of Cerebral is driven by the goal to give you insight. Creating a Cerebral application allows you and your team members to never question what actually happens when a page loads, a button is clicked, etc.\n\nThe Cerebral debugger is what gives you this insight and answers your questions on what state changes and side effects have been run in any given situation. It is a powerful tool that makes it easier to reason about the application and increases productivity in planning out logic and implementation.\n\nCerebral is based on the simple concept of three things your application does in order to function. **Store state**, **render state** and **update state**.\n\n## Store state\n\nWhere to store the state of an application is a highly debated subject. Should we allow the components to store state? Should we have multiple models? Stores? Reducers? Services? There are many concepts that can store state. In Cerebral you store all your state in \"a single state tree\". That means you do not create classes or other abstractions around state, it is all basically one big object of plain JavaScript types. Objects, arrays, strings, numbers and booleans:\n\n```js\n{\n auth: {\n isLoggedIn: false,\n user: {\n prefs: {\n style: 'light'\n },\n friends: [],\n info: {\n email: '',\n name: ''\n }\n }\n },\n posts: {\n list: [],\n selectedPostIndex: 0\n }\n}\n```\n\nWith this approach we get some benefits not possible with other approaches.\n\n1. **Simple and consistent API** - Typically a state update changes a value, pushes an item in a list, or merges an object into another. With a single state tree we can create an API that does exactly that:\n\n```js\nstate.set('auth.user.prefs.style', 'dark')\nstate.push('auth.user.friends', 'Joe')\nstate.merge('auth.user.info', {\n email: '[email protected]',\n name: 'Cheetah'\n})\n```\n\nWith a single state tree we can point to parts of the state using paths (the first argument).\n\n2. Cerebral does not look at the updates in your application as \"value updates\", but as \"path updates\". This allows Cerebral to make optimizations not possible in other frameworks.\n\n3. There is no need for immutability in Cerebral because a change to a path means that any component depending on that path should render (no value comparison). In applications with large data structures, immutability has a high cost. There is no need to hack objects and arrays to observe changes to them either. There is nothing special about the state you put into Cerebral's state tree.\n\n4. Since there is no value comparison in Cerebral it uses what we call **strict render**. This allows us to do render optimizations not possible with other solutions. For example you can say that a component that depends on a list is only interested in added/removed items of the list or whether the list itself is being replaced.\n\n5. When the state of the application is a single object, we can use an object inspector to visualize the whole state of your application. With the Cerebral debugger it is easy to build a mental image of application state. You can even make changes directly to state to see how it affects the view layer.\n\n## Render state\n\nSince Cerebral stores all the state of the application in a single state tree, we need a way to expose that state to the components. In some frameworks this is done by passing the whole model or collection of models/stores from the top of the application and down from one component to the next. This can become very tedious and fragile as all nested components completely depend on their parent. In Cerebral, the state of the application is directly connected to each component (here shown with **React**):\n\n```js\nconnect({\n userName: state`auth.user.info.name`\n})(function User(props) {\n props.userName // \"some name\" (value stored in 'app.user.name')\n})\n```\n\n**connect** tells Cerebral that the component is interested in a path where the user name happens to be. When that path changes, then the component will be rendered. The component is now completely independent of other components. You can move it to wherever you desire in the component tree and it will still work.\n\n## Update state\n\nThis is where Cerebral differs most from other approaches to application development. Updating the state of an application can be anything from:\n\n* flipping a **true** to a **false**\n* setting some value, like a filter\n* reading (and storing) something in local storage\n* requesting data from the server and, depending on the status code of the response, doing something with that response which might lead to new requests and/or setting up a listener for data on the server\n* etc...\n\nThe point is, updating state can be a very complex flow of operations. This is often where spaghetti code comes from, and we use abstractions to hide it. The problem with abstractions hiding too much logic is that it becomes rigid, making it difficult to reuse logic and compose existing logic together in new ways.\n\nTo handle everything from a simple toggle to very complex operations, Cerebral has the concept of **sequences**. Sequences allows you to compose functions together into a **flow**. You can define different execution paths based on whatever you want (a status code, an error, some state, etc). This allows you to write decoupled code, while still bringing everything together in the form of a higher abstraction which helps developers understand how things relate to one another (in what order they will run, when they will run, etc). Under the hood, sequences are based on [function-tree](https://github.com/cerebral/cerebral/tree/master/packages/node_modules/function-tree), a project that came out of the initial experimentations in the first version of Cerebral.\n","title":"The architecture"},"tutorial":{"raw":"# Tutorial\n\nIf you are interested in the concepts of Cerebral you can read [an introduction to the architecture](/docs/introduction/the_architecture) or [dig into the details](/docs/advanced/index)\n\nAs you read through the introductory chapters it can be a good idea to follow along in your local environment. Follow the [get started](/docs/introduction) guide and download the debugger as well. When you see section like this:\n\n```marksy\n<Info>\nIt means you get some general information or a tip about the topic at hand.\n</Info>\n```\n\nAnd when you see this:\n\n```marksy\n<Warning>\nIt is important that you read it to avoid being confused by something.\n</Warning>\n```\n\nPlease have a look at the follow Codesandbox to understand how all the concepts builds an application:\n\n```marksy\n<Codesandbox id=\"cerebral-todomvc-7ke4u\" />\n```\n","title":"Tutorial"},"modules":{"raw":"# Modules\n\nThe main building block of Cerebral is the **Module**. It helps you organize your application and it is an extension point to share logic between apps. In your project open the file `src/index.js`. Add the following content:\n\n```js\nimport App from 'cerebral'\n\nconst app = App({\n state: {\n title: 'My Project'\n }\n})\n```\n\n**That is it!** Cerebral is now wired up and we can start building the application. When your application grows you can extend a module with submodules:\n\n```js\nimport App from 'cerebral'\n\nconst app = App({\n state: {\n title: 'My Project'\n },\n modules: {\n someOtherModule: {\n state: {}\n }\n }\n})\n```\n\nBut before looking more into organizing your project, let us look at the devtools.\n","title":"Modules"},"devtools":{"raw":"# Devtools\n\n## Install debuger\n\n[Download the Debugger](https://github.com/cerebral/cerebral-debugger/releases) for your target OS:\n\n* **Mac**: cerebral-debugger-x.x.x.dmg\n* **Windows**: cerebral-debugger-setup-x.x.x.exe\n* **Linux**: cerebral-debugger_x.x.x_amd64.deb\n\n## Initialize\n\nYou initialize the devtools by adding it to the app. In the **index.js** file you can adjust the content to:\n\n```js\nimport { App } from 'cerebral'\nimport Devtools from 'cerebral/devtools'\n\nconst app = App({\n state: {\n title: 'My Project'\n } \n}, {\n devtools: Devtools({\n // This should point to the host and port you\n // create in the Devtools application\n host: 'localhost:8585'\n })\n})\n```\n\n```marksy\n<Info>\nNote that if you are developing a native application you will most likely have to use your IP address instead of \"localhost\", when connecting to the Devtools\n</Info>\n```\n\nOpen up the newly installed debugger and add a new application.\n\n```marksy\n<Image src=\"/images/add_app.png\" style={{ width: 400 }} />\n```\n\nIf you refresh your application and go to the **state** tab you should now see:\n\n```js\n{\n title: 'My Project'\n}\n```\n","title":"Devtools"},"state":{"raw":"# State\n\nCerebral uses a single state tree to store all the state of your application. Even though you split up your state into modules, at the end of the day it will look like one big tree:\n\n```js\n{\n title: 'My Project',\n someOtherModule: {\n foo: 'bar'\n }\n}\n```\n\nYou will normally store other objects, arrays, strings, booleans and numbers in it. Forcing you to think of your state in this simple form gives us benefits.\n\n1. The state of the application is exposed as simple values. There are no classes or other abstractions hiding the state of your application\n2. The state can be stored on the server, local storage and passed to the debugger. It is what we call **serializable** state\n3. All the state of your application can be inspected through one object\n4. All state is related to a path. There is no need to import and/or pass around model instances into other model instances to access state\n\nLet us add some new state to the application to show of some more Cerebral. In our **main/index.js** file:\n\n```js\nimport { App } from 'cerebral'\nimport Devtools from 'cerebral/devtools'\n\nconst app = App({\n state: {\n title: 'My Project',\n posts: [],\n users: {},\n userModal: {\n show: false,\n id: null\n },\n isLoadingItems: false,\n isLoadingUser: false,\n error: null\n } \n}, {...})\n```\n\nWe are going to load posts from [JSONPlaceholder](https://jsonplaceholder.typicode.com). We also want to be able to click a post to load information about the user who wrote it, in a modal. For this to work we need some state. All the state defined here is pretty straight forward, but why do we choose an array for the posts and an object for the users?\n\n## Storing data\n\n**Data** in this context means entities from the server that are unique, they have a unique *id*. Both posts and users are like this, but we still choose to store posts as arrays and users as an object. Choosing one or the other is as simple as asking yourself, \"What am I going to do with the state?\". In this application we are only going to map over the posts to display a list of posts, nothing more. Arrays are good for that. But users here are different. We want to get a hold of the user in question with an id, *userModal.id*. Objects are very good for this. Cause we can say:\n\n```js\nusers[userModal.id]\n```\n\nNo need to iterate through an array to find the user. Normally you will store data in objects, because you usually have the need for lookups. An object also ensures that there will never exist two entities with the same id, unlike in an array.","title":"State"},"providers":{"raw":"# Providers\n\nProviders is a term in Cerebral that basically means _side effects_. Everything from talking to the server, browser APIs etc. should be contained in providers. This has several benefits:\n\n1. You are encouraged to build an explicit API for doing side effects in your application\n\n2. The providers are automatically tracked by the debugger, giving you insight of their usage\n\n3. When running tests a provider is easy to mock and can be automatically mocked by the snapshot tests\n\nIn our application we want to talk to a service called [JSONPlaceholder](https://jsonplaceholder.typicode.com/) and for that we need a provider. You can choose any library to talk to the server, but we will just use the browser standard [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).\n\n```js\nimport { App } from 'cerebral'\nimport Devtools from 'cerebral/devtools'\n\nconst API_URL = 'https://jsonplaceholder.typicode.com'\n\nconst app = App({\n state: {\n title: 'My Project',\n posts: [],\n users: {},\n userModal: {\n show: false,\n id: null\n },\n isLoadingPosts: false,\n isLoadingUser: false,\n error: null\n },\n providers: {\n api: {\n getPosts() {\n return fetch(`${API_URL}/posts`)\n .then(response => response.toJSON())\n },\n getUser(id) {\n return fetch(`${API_URL}/users/${id}`)\n .then((response) => response.json())\n }\n }\n } \n}, {...})\n```\n\nWe have now added a provider that uses the native fetch API of the browser to grab posts and users from JSONPlaceholder. Instead of creating a generic http provider we went all the way and created a specific provider for talking to JSONPlaceholder called **api**. The concept of a provider allows us to do this and it is highly encouraged as it will improve the readability of the application code.\n\nWe are now ready to make some stuff happen in our application!\n","title":"Providers"},"sequences":{"raw":"# Sequences\n\nApplication development is about handling events to run side effects and produce changes to the state. This event can be anything from a user interaction or some other internal event in the application.\n\nWe need two pieces of logic for our application. **openPostsPage** and **openUserModal**. Let us look at how you might think this logic is commonly implemented:\n\n```js\nimport { App } from 'cerebral'\nimport Devtools from 'cerebral/devtools'\n\nconst API_URL = 'https://jsonplaceholder.typicode.com'\n\nconst app = App({\n state: {\n title: 'My Project',\n posts: [],\n users: {},\n userModal: {\n show: false,\n id: null\n },\n isLoadingPosts: false,\n isLoadingUser: false,\n error: null\n },\n methods: {\n openPostsPage() {\n this.state.isLoadingPosts = true\n this.providers.getPosts()\n .then((posts) => {\n this.state.posts = posts\n this.state.isLoadingPosts = false\n })\n }\n openUserModal(id) {\n this.state.isLoadingUser = true\n this.providers.getUser(id)\n .then((user) => {\n this.state.users[id] = user\n this.state.currentUserId = id\n this.state.isLoadingUser = false\n })\n }\n },\n providers: {...} \n}, {...})\n```\n\nThis is an **imperative** approach to managing application logic, using methods. In Cerebral we do not use an imperative approach, but a functional one. That means instead of methods we use **sequences**. Let us review what we want to happen before we dive into it:\n\n1. Set that we are loading the posts\n2. Go grab the posts\n3. Add the posts\n4. Unset that we are loading the posts\n\nWe can mock out this **sequence** in our main module:\n\n```js\nimport { App } from 'cerebral'\nimport Devtools from 'cerebral/devtools'\n\nconst API_URL = 'https://jsonplaceholder.typicode.com'\n\nconst app = App({\n state: {\n title: 'My Project',\n posts: [],\n users: {},\n userModal: {\n show: false,\n id: null\n },\n isLoadingPosts: false,\n isLoadingUser: false,\n error: null\n },\n sequences: {\n openPostsPage: [\n setLoadingPosts,\n getPosts,\n setPosts,\n unsetLoadingPosts\n ]\n },\n providers: {...} \n}, {...})\n```\n\nAs you can see we can just write out exactly what we want to happen. This allows us to reason about **what** we want our application to do before we think about **how** to do it.\n\n```marksy\n<Info>\nWhen a sequence triggers you can pass in **props**. These props can be accessed by any function\nin the sequence. In this example the props would contain the id of the user we want to fetch.\n</Info>\n```\n\nWe are now going to do the actual implementation:\n\n```js\nimport App from 'cerebral'\nimport Devtools from 'cerebral/devtools'\n\nconst API_URL = 'https://jsonplaceholder.typicode.com'\n\nconst setLoadingPosts = ({ store }) =>\n store.set('isLoadingPosts', true)\n\nconst getPosts = ({ api }) =>\n api.getPosts().then(posts => ({ posts }))\n\nconst setPosts = ({ store, props }) =>\n store.set('posts', props.posts)\n\nconst unsetLoadingPosts = ({ store }) =>\n store.set('isLoadingPosts', false)\n\nconst app = App({\n state: {\n title: 'My Project',\n posts: [],\n users: {},\n userModal: {\n show: false,\n id: null\n },\n isLoadingPosts: false,\n isLoadingUser: false,\n error: null\n },\n sequences: {\n openPostsPage: [\n setLoadingPosts,\n getPosts,\n setPosts,\n unsetLoadingPosts\n ]\n },\n providers: {...} \n}, {...})\n```\n\n## Actions\n\nAs you can see every function run in the sequence has access to **store**, **props** and our own **api** is available as well. We call these functions **actions** and Cerebral builds a context for them when they run. This context is passed in as the only argument. This context is where the store API allows you to do different changes on the state of the application. The props holds values passed into the sequence and populated through the execution.\n\nWhen **api.getPosts** runs we put the returned posts on an object. This object is merged into the **props** of the sequence, as visualized here:\n\n```js\n[\n setLoadingPosts, // {}\n getPosts, // {}\n setPosts, // { posts }\n unsetLoadingPosts // { posts }\n]\n```\n\nLet us fire up the sequence and we can rather let the debugger do this visualization for us. In the `/src/index.js` add the following:\n\n```js\n...\n\nconst app = App({...}, {...})\n\nconst openPostsPage = app.getSequence('openPostsPage')\n\nopenPostsPage()\n```\n\nWhen you refresh the application now you should see the debugger show you that the *openPostsPage* sequence has triggered. Play around with the checkboxes at the top of the execution window in the debugger to adjust the level of detail.\n\n## Factories\n\nBut we can actually refactor our *openPostsPage* sequence a bit. A concept in functional programming called *factories* allows you to create a function by calling a function. What we want to create are functions that changes the state of the application. Luckily for us Cerebral ships with several factories that allows you to express state changes and other things directly in your sequences.\n\nLet us refactor the code and also add the sequence for loading a user. What to take notice of here is that we are using the **state** and **props** [template literal tags](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals). These tags can be used to tell the factories what you are targeting, at what path:\n\n```js\nimport App, { state, props } from 'cerebral'\nimport Devtools from 'cerebral/devtools'\nimport { set } from 'cerebral/factories'\n\nconst API_URL = 'https://jsonplaceholder.typicode.com'\n\nconst getPosts = ({ api }) =>\n api.getPosts().then(posts => ({ posts }))\n\nconst getUser = ({ api, props }) =>\n api.getUser(props.id).then(user => ({ user }))\n\nconst app = App({\n state: {\n title: 'My Project',\n posts: [],\n users: {},\n userModal: {\n show: false,\n id: null\n },\n isLoadingPosts: false,\n isLoadingUser: false,\n error: null\n },\n sequences: {\n openPostsPage: [\n set(state`isLoadingPosts`, true),\n getPosts,\n set(state`posts`, props`posts`),\n set(state`isLoadingPosts`, false)\n ],\n openUserModal: [\n set(state`userModal.id`, props`id`),\n set(state`userModal.show`, true),\n set(state`isLoadingUser`, true),\n getUser,\n set(state`users.${props`id`}`, props`user`),\n set(state`isLoadingUser`, false)\n ]\n },\n providers: {...} \n}, {...})\n\nconst openPostsPage = app.getSequence('openPostsPage')\n\nopenPostsPage()\n```\n\nWe now just made several actions obsolete. There are other factories for changing state and also managing the flow of execution.\n","title":"Sequences"},"organize":{"raw":"# Organize\n\nOur file is starting to get a bit verbose. Let us look into how you typically organize a Cerebral application.\n\n## Create a main module\n\nWe will first move the logic for defining the module into its own file under `src/main/index.js`:\n\n```js\nimport * as sequences from './sequences'\nimport * as providers from './providers'\n\nexport default {\n state: {\n title: 'My Project',\n posts: [],\n users: {},\n userModal: {\n show: false,\n id: null\n },\n isLoadingPosts: false,\n isLoadingUser: false,\n error: null\n },\n sequences,\n providers\n}\n```\n\n## Create an actions file\n\nOur actions should be contained in its own file at `src/main/actions.js`:\n\n```js\nimport { state } from 'cerebral'\n\nexport const getPosts = ({ api }) =>\n api.getPosts().then(posts => ({ posts }))\n\nexport const getUser = ({ api, props }) =>\n api.getUser(props.id).then(user => ({ user }))\n```\n\n## Create a sequences file\n\nThe same for sequences at `src/main/sequences.js`:\n\n```js\nimport { set } from 'cerebral/factories'\nimport { state, props } from 'cerebral'\nimport * as actions from './actions'\n\nexport const openPostsPage = [\n set(state`isLoadingPosts`, true),\n actions.getPosts,\n set(state`posts`, props`posts`),\n set(state`isLoadingPosts`, false)\n]\n\nexport const openUserModal = [\n set(state`userModal.show`, true),\n set(state`userModal.id`, props`id`),\n set(state`isLoadingUser`, true),\n actions.getUser,\n set(state`users.${props`id`}`, props`user`),\n set(state`isLoadingUser`, false),\n]\n```\n\n## Create a provider file\n\nJup, that's right! `src/main/providers.js`:\n\n```js\nconst API_URL = 'https://jsonplaceholder.typicode.com'\n\nexport const api = {\n getPosts() {\n return fetch(`${API_URL}/posts`)\n .then(response => response.toJSON())\n },\n getUser(id) {\n return fetch(`${API_URL}/users/${id}`)\n .then(response => response.toJSON())\n }\n}\n```\n\n## We are left with\n\nIn our `src/index.js` file we are now left with:\n\n```js\nimport App from 'cerebral'\nimport Devtools from 'cerebral/devtools'\nimport main from './main'\n\nconst app = App(main, {\n devtools: Devtools({\n host: 'localhost:8585'\n })\n})\n\nconst openPostsPage = app.get(sequences.openPostsPage)\n\nopenPostsPage()\n```\n\nNow this looks a lot cleaner and scalable. By adding a `modules` directory to `src/main` you can add more modules with domain specific names like **admin** or **posts**. These modules are added to the main module.","title":"Organize"},"views":{"raw":"# Views\n\nThere are several views you can connect Cerebral to and it is mostly a matter of preference. Let us look at a couple of examples.\n\nVue is out first, [Vue](https://vuejs.org/):\n\n`npm install vue @cerebral/vue`\n\n```js\nimport App from 'cerebral'\nimport Devtools from 'cerebral/devtools'\nimport Vue from 'vue/dist/vue'\nimport { Container, connect } from '@cerebral/vue'\nimport AppComponent from './components/App'\nimport main from './main'\n\nconst app = App(main, {\n devtools: Devtools({\n host: 'localhost:8585'\n })\n})\n\nconst loadItemsPage = app.get(sequences.loadItemsPage)\n\nloadItemsPage()\n\nnew Vue({\n render: h =>\n h({\n components: {\n Container: Container(app),\n AppComponent: AppComponent\n },\n template: \"<Container><AppComponent></AppComponent></Container>\"\n })\n}).$mount(\"#app\");\n```\n\nAnd you would define the component like this:\n\n```js\nimport { connect } from '@cerebral/vue'\nimport { state, sequences } from 'cerebral'\n\nexport default connect(\n {\n posts: state`posts`,\n isLoadingItems: state`isLoadingItems`,\n openUserModal: sequences`openUserModal`\n },\n {\n template: `\n <div v-if=\"isLoadingItems\" className=\"content\">\n <h4>Loading posts...</h4>\n </div>\n <div v-else className=\"content\">\n <div className=\"posts\">\n <div\n v-for=\"post in posts\"\n className=\"post\"\n v-on:click=\"openUserModal({ id: post.userId })\"\n >\n {{ post.title }}\n </div>\n </div>\n </div>\n`\n }\n)\n```\n\nYou would of course be able to use **.vue** files as well here. Read more about that in [@cerebral/vue](/views/vue.html).\n\nThe tutorial will continue using [React](https://reactjs.org/) though. Run the following command in the terminal:\n\n`npm install react react-dom @cerebral/react`\n\nAnd reset the **index.html** file to:\n\n```html\n<div id=\"app\"></div>\n```\n\nAnd then in the root **index.js** file you can add:\n\n```js\nimport App from 'cerebral'\nimport Devtools from 'cerebral/devtools'\nimport React from 'react'\nimport { render } from 'react-dom'\nimport { Container } from '@cerebral/react'\nimport AppComponent from './components/App'\nimport main from './main'\n\nconst app = App(main, {\n devtools: Devtools({\n host: 'localhost:8585'\n })\n})\n\nrender(\n <Container app={app}>\n <AppComponent />\n </Container>,\n document.querySelector('#app')\n)\n```\n\nAnd your **App** component located in `src/components/App.js` could look like:\n\n```js\nimport React from 'react'\nimport { state, sequences } from 'cerebral'\nimport { connect } from '@cerebral/react'\n\nexport default connect(\n {\n posts: state`posts`,\n openUserModal: sequences`openUserModal`\n },\n function App({ posts, openUserModal }) {\n return (\n <div className=\"posts\">\n {posts.map(post => (\n <div\n className=\"post\"\n onClick={() => openUserModal({ id: post.userId })}\n >\n {post.title}\n </div>\n ))}\n </div>\n )\n }\n)\n```\n\nThe point is that for Cerebral it does not really matter. Cerebral is responsible for your state, state changes and side effects. You can use whatever to convert your state into a UI for your users.\n\nFrom this point you are hopefully able to start exploring on your own. Continue looking into more advanced concepts and guides.\n","title":"Views"}},"advanced":{"index":{"raw":"# Compute\n\nNormally you use state directly from the state tree, but sometimes you need to compute state. Typically filtering lists, grabbing the projects of a user, or other derived state. It is a good idea not to put this kind of logic inside your view layer, cause by creating a computed you can reuse the logic anywhere and it will automatically optimize the need to recalculate the value.\n\n## Create a computed\n\nCerebral allows you to compute state that can be used in multiple contexts. Let us look at an example:\n\n```js\nimport { state } from 'cerebral'\n\nexport const filteredList = (get) => {\n const items = get(state`items`)\n const filter = get(state`filter`)\n\n return items.filter((item) => item[filter.property] === filter.value)\n}\n```\n\nA computed is just a function that receives the `get` argument. You use this argument to retrieve the state of the application. This retrieval is tracked, meaning that the computed automatically optimizes itself.\n\nYou attach a computed to the state of your application:\n\n```js\nimport { filteredList } from './computed'\n\nexport default {\n state: {\n items: [],\n filter: {\n property: 'isAwesome',\n value: true\n },\n filteredList\n }\n}\n```\n\n## With components\n\nHere shown with *React*:\n\n```js\nimport { state } from 'cerebral'\n\nconnect(\n {\n list: state`filteredList`\n },\n function List({ list }) {\n return <ul>{list.map((item) => <li>{item.title}</li>)}</ul>\n }\n)\n```\n\n## With factories\n\n```js\nimport { when } from 'cerebral/factories'\nimport { state } from 'cerebral'\n\nexport const mySequence = [\n when(state`appIsAwesome`),\n {\n true: [],\n false: []\n }\n]\n```\n\n## With actions\n\n```js\nimport { state } from 'cerebral'\n\nexport function myAction({ get }) {\n const filteredList = get(state`filteredList`)\n}\n```\n\n## With other tags\n\n```js\nimport { state } from 'cerebral'\nimport { set } from 'cerebral/factories'\n\nexport const mySequence = set(state`${state`somePropKey`}.bar`, 'baz')\n```\n\n## Computing computeds\n\n```js\nimport { state, props } from 'cerebral'\n\nexport const fooBar = (get) => get(state`foo`) + get(state`bar`)\n\nexport const fooBarBaz = (get) => get(state`fooBar`) + get(state`baz`)\n```\n\nYou point to computeds as normal state and you also use them that way.\n\n## With props\n\nYou can also combine computeds with props. Either from a component or you can explicitly pass props when used in an action.\n\n```js\nimport { state, props } from 'cerebral'\n\nexport const itemUsers = (get) => {\n const itemKey = get(props`itemKey`)\n const item = get(state`items.${itemKey}`)\n\n return item.userIds.map((userId) => get(state`users.${userId}`))\n}\n```\n\nIn this example we have items with an array of user ids. We create a computed taking in **itemKey** as a prop, extracts the item and then iterates the userIds to grab the actual users. Now this computed will only recalculate when the item or any of the users grabbed updates.\n\nThe computed we created here requires a prop and can be used in for example an action doing:\n\n```js\nimport { state } from 'cerebral'\n\nfunction myAction({ get }) {\n const itemUsers = get(state`itemUsers`, { itemKey: '123' })\n}\n```\n\nOr with a component, here showing with *React*:\n\n```js\nimport React from 'react'\nimport { connect } from '@cerebral/react'\nimport { state } from 'cerebral'\n\nexport default connect(\n {\n users: state`itemUsers`\n },\n function ({ users }) {\n return ...\n }\n)\n```\n\nAnd then you would pass the **itemKey** when using the component:\n\n```js\n<ItemUsers itemKey=\"123\" />\n```\n\nNow this component only renders when the item changes or any related users. Even if users are added/removed from the item it will know about this en recalculate correctly.\n\n```marksy\n<Info>\nComputeds that uses props and are connected to components will actually be cloned under the hood.\nThis ensures that when you use the same computed, for example for a list, they will all individually cached. When the component unmounts the clone is destroyed.\n</Info>\n```\n","title":"Compute"},"errors":{"raw":"# Errors\n\nCurrently we are creating a nested structure in our sequence to express conditional execution. Related to errors that does not always make sense, cause you just want to stop execution and do something completely different. Let us revert our sequence back to is original format and then we rather catch the error:\n\n```js\nimport { set } from 'cerebral/factories'\nimport { state, props } from 'cerebral'\n\nconst getUser = ({ jsonPlaceholder, props }) =>\n jsonPlaceholder.getUser(props.id).then(user => ({ user }))\n\nexport default {\n state: {\n title: 'My Project',\n users: {},\n currentUserId: null,\n isLoadingUser: false,\n error: null\n },\n sequences: {\n loadUser: [\n set(state`isLoadingUser`, true),\n getUser,\n set(state`users.${props`id`}`, props`user`),\n set(state`currentUserId`, props`id`),\n set(state`isLoadingUser`, false)\n ]\n },\n catch: [\n [Error, set(state`error`, props`error.message`)]\n ],\n providers: {...}\n}\n```\n\nThe **catch** takes a list of error handlers. You define the handler with an error type and the sequence to run, in this case just one action. In this case we are catching any error, but we could be more specific.\n\n```marksy\n<Warning>\nNotice that the catch handler is an array of arrays. Each item in the array is an array of two items. The type of error to handle and what sequence should handle it.\n</Warning>\n```\n\nLet us create a **JsonPlaceholderError**:\n\n```js\nimport { set } from 'cerebral/factories'\nimport { CerebralError, state, props } from 'cerebral'\n\nclass JsonPlaceholderError extends CerebralError {\n constructor(message, statusCode) {\n super(message)\n this.statusCode = statusCode\n this.name = 'JsonPlaceholderError'\n }\n}\n\nconst getUser = ({ jsonPlaceholder, props }) =>\n jsonPlaceholder.getUser(props.id).then(user => ({ user }))\n\nexport default {\n state: {...},\n sequences: {\n loadUser: [\n set(state`isLoadingUser`, true),\n getUser,\n set(state`users.${props`id`}`, props`user`),\n set(state`currentUserId`, props`id`),\n set(state`isLoadingUser`, false)\n ]\n },\n catch: [\n [JsonPlaceholderError, set(state`error`, props`error.message`)]\n ],\n providers: {...}\n}\n```\n\nAnd we can throw it from our provider:\n\n```js\nimport { Provider } from 'cerebral'\nimport { JsonPlaceholderError } from './errors'\n\nexport const jsonPlaceholder = Provider({\n getUser(id) {\n return fetch(`https://jsonplaceholder.typicode.com/users/${id}`)\n .then((response) => {\n if (response.status >= 200 && response.status < 300) {\n return response.json()\n } else {\n return response.text().then((message) => {\n throw new JsonPlaceholderError(message, response.status)\n })\n }\n })\n .then((user) => ({ user }))\n .catch((error) => {\n throw new JsonPlaceholderError(error.message, 0)\n })\n }\n})\n```\n\nLet us force an error to see how it looks. First let us actually handle the error by creating a new sequence in our **sequences.js** file:\n\n```js\nimport * as actions from './actions'\nimport { set } from 'cerebral/factories'\nimport { state, props } from 'cerebral'\n\nexport const handleError = set(state`error`, props`error.message`)\n\nexport const loadUser = [...]\n```\n\nNow let us throw an error when our provider runs:\n\n```js\nimport { Provider } from 'cerebral'\nimport { JsonPlaceholderError } from './errors'\n\nexport const jsonPlaceholder = Provider({\n getUser(id) {\n throw new JsonPlaceholderError('Wuuut', 0)\n /*\n THE ORIGINAL CODE\n */\n }\n})\n```\n\nAs you can see the debugger indicates when it catches an error and how it is handled. Note that by default Cerebral will not throw to the console when these caught errors occur, but just give you a warning about it. You can force Cerebral to also throw to the console by passing in an option to the controller:\n\n```js\nimport App from 'cerebral'\nimport main from './main'\n\nlet Devtools = null\nif (process.env.NODE_ENV === 'development') {\n Devtools = require('cerebral/devtools').default\n}\n\nconst app = App(main, {\n throwToConsole: true,\n devtools: Devtools({\n host: 'localhost:8585'\n })\n})\n```\n","title":"Errors"},"factories":{"raw":"# Factories\n\nA common concept in functional programming is factories. A factory is basically a function that creates a function:\n\n```js\nfunction createMessager(name) {\n function message(msg) {\n return `${name}, ${msg}`\n }\n\n return message\n}\n\nconst message = createMessager('Bob')\n\nmessage('what is happening?') // \"Bob, what is happening?\"\n```\n\nCreating a factory gives you the possibility to configure what a function should do before it is run. This is a perfect concept for Cerebral.\n\n## Some example factories\n\nSo the typical factories you use with Cerebral changes the state:\n\n```js\nimport { set, push } from 'cerebral/factories'\nimport { state } from 'cerebral'\n\nexport default [\n set(state`foo`, 'bar'),\n push(state`list`, 'foo')\n]\n```\n\nBut you could also create a factory to for example get data from the server:\n\n```js\nimport { state, props } from 'cerebral'\nimport { set } from 'cerebral/factories'\nimport { httpGet } from './myFactories'\n\nexport default [\n httpGet('/items'),\n set(state`items`, props`response.data`)\n]\n```\n\nSo how would this **httpGet** factory actually work? Let us dissect it.\n\n## Dissecting a factory\n\nThe **httpGet** factory above could look something like this:\n\n```js\nfunction httpGetFactory(url) {\n function httpGetAction({ http }) {\n return http.get(url).then(response => ({ response }))\n }\n\n return httpGetAction\n}\n```\n\nWhen **httpGet** is called it will return a function, an action, for us. This action is configured with a url and when it is called it will run a method on a provider we have named **http**. In this case the http provider calls the server and returns the response to props as `{ response: [...] }`.\n\nBut **httpGet** actually has more features than this. You can use a *string tag* instead of a normal string.\n\n```js\nimport { state, props, string } from 'cerebral'\nimport { set } from 'cerebral/factories'\nimport { httpGet } from './myFactories'\n\nexport default [\n httpGet(string`items/${props.itemId}`),\n set(state`item`, prop`response.data`)\n]\n```\n\nHere we have configured our function to produce the url based on the property **itemId** passed through the signal. How do we handle that inside our operator?\n\n### Resolve values\n\nInstead of using the url directly, like we do here:\n\n```js\nfunction httpGetFactory(url) {\n function httpGetAction({ http }) {\n return http.get(url).then(response => ({ response }))\n }\n\n return httpGetAction\n}\n```\n\nWe can rather resolve it, using the **get** provider:\n\n```js\nfunction httpGetFactory(url) {\n function httpGetAction({ http, get }) {\n return http.get(get(url)).then(response => ({ response }))\n }\n\n return httpGetAction\n}\n```\n\nBy using **get** we allow passing in a value to be evaluated. It can still be just a plain string, no worries, but now we can also use tags.\n\n### Optional paths\n\nThe sequences of Cerebral a pretty cool feature which allows you to optionally use paths. For example:\n\n```js\nimport { httpGet } from './myFactories'\n\nexport default [\n httpGet('/items'),\n {\n sucess: [],\n error: []\n }\n]\n```\n\nYou can even base the paths on status codes:\n\n```js\nimport { httpGet } from './myFactories'\n\nexport default [\n httpGet('/items'),\n {\n success: [],\n 404: [],\n error: []\n }\n]\n```\n\nThis gives a lot of flexibility, but how does it work? Let us do some more digesting:\n\n```js\nfunction httpGetFactory(url) {\n function httpGetAction({ http, get, path }) {\n if (path) {\n // More to come\n } else {\n return http.get(get(url)).then(response => ({ response }))\n }\n }\n\n return httpGetAction\n}\n```\n\nWe can actually check if **path** exists on the context of the action. If it does not exist, it means that the action can not diverge execution down a path. That means we can support both scenarios:\n\n```js\nimport { state, props } from 'cerebral'\nimport { set } from 'cerebral/factories'\nimport { httpGet } from './myFactories'\n\nexport const scenarioA = [\n httpGet('/items'),\n {\n sucess: set(state`items`, props`response.data`),\n error: []\n }\n]\n\nexport const scenarioB = [\n httpGet('/items'),\n set(state`items`, props`response.data`)\n]\n```\n\n```js\nfunction httpGetFactory(url) {\n function httpGetAction({ http, get, path }) {\n if (path) {\n return http\n .get(get(url))\n .then((response) => {\n return path.success({ response })\n })\n .catch((error) => {\n return path.error({ error })\n })\n } else {\n return http.get(get(url)).then(response => ({ response }))\n }\n }\n\n return httpGetAction\n}\n```\n\nSo based on the path existing or not we call the expected *success* and *error* paths respectively.\n\nBut what about the status codes? Lets extend our example:\n\n```js\nfunction httpGetFactory(url) {\n function httpGetAction({ http, get, path }) {\n if (path) {\n return http\n .get(get(url))\n .then((response) => {\n return path[response.status]\n ? path[response.status]({ response })\n : path.success({ response })\n })\n .catch((error) => {\n return path[error.status]\n ? path[error.status]({ error })\n : path.error({ error })\n })\n } else {\n return http.get(get(url)).then(response => ({ response }))\n }\n }\n\n return httpGetAction\n}\n```\n\n### Resolve tag paths\n\nYou can also resolve the paths of a tag. For example:\n\n```js\nstate`foo.bar`\n```\n\nThe path in this example is **foo.bar**. Or:\n\n```js\nstate`items.${props`itemId`}`\n```\n\nThis might resolve to **items.123**.\n\nResolving the path instead of the value within the path gives some contextual power. For example the core Cerebral factories uses this feature:\n\n```js\nimport { set } from 'cerebral/factories'\nimport { state, props } from 'cerebral'\n\nexport default set(state`foo`, props`foo`)\n```\n\nSo here we are using two tags, **state** and **props**, and they have two different contextual meanings. The **state** tag is used to identify *where* to put a value, and the **props** tag is used to identify *what* value.\n\n```js\nfunction setFactory(target, value) {\n function set({ store, resolve }) {\n // First we identify that we have the tag\n // type we want\n const isStateTag = resolve.isTag(target, 'state')\n\n // We use the type of tag to identify\n // where we want to do a \"set\"\n if (isStateTag) {\n // We extract the path, \"foo\", so that\n // we know where to set the value\n const statePath = resolve.path(target)\n\n // We do a normal \"store.set\" with the\n // resolved path and value\n store.set(statePath, resolve.value(value))\n } else {\n throw new Error('Target must be a state tag')\n }\n }\n\n return set\n}\n\nexport default setFactory\n```\n\n## Enhancing your factories\n\nYou will very likely create a lot of action factories in your application. This drys up your code and makes your sequences more expressive. If you start using the **get** provider, and even the **resolver**, you can make your factories even more expressive. One such factory could be notifying the user:\n\n```js\nimport { notify } from './myFactories'\nimport { string, state } from 'cerebral'\n\nexport default notify(string`Sorry ${state`user.name`}, this does not work :(`)\n```\n\nThe factory could look something like this:\n\n```js\nimport { state } from 'cerebral'\n\nfunction notifyFactory(message) {\n function notifyAction({ store, get }) {\n store.set('message', get(message))\n }\n\n return notifyAction\n}\n```\n\n## Summary\n\nYou might build your whole application without taking advantage of resolving tags in your factories, but it is a powerful concept that can express more logic in your sequence definitions making your code even more readable.\n","title":"Factories"},"reactions":{"raw":"# Reactions\n\nSometimes you need to react to changes of the state. You might want to run a sequence related to a change of the state or maybe some logic inside a component. Reactions allows you to express this kind of logic.\n\n## Reactions in modules\n\nWhen you create a module you can attach a reaction to it:\n\n```js\nimport * as reactions from './reactions'\n\nexport default {\n state: {},\n reactions\n}\n```\n\nSo you would typically create your reactions in a separate file, *reactions.js*:\n\n```js\nimport { Reaction } from 'cerebral'\nimport { state, sequences } from 'cerebral'\n\nexport const pageChanged = Reaction(\n {\n page: state`currentPage`\n },\n ({ page, get }) => {\n get(sequences`openPage`)({ page })\n }\n)\n```\n\nThis reaction will react to whenever the current page is changed and fire off the **openPage** signal, with the new page.\n\n## Reactions in views\n\nYou can also create reactions inside views, here shown with *React*:\n\n```js\nimport * as React from 'react'\nimport { connect } from '@cerebral/react'\nimport { state, sequences } from 'cerebral'\n\nexport default connect(\n {\n inputValue: state`inputValue`,\n changeInputValue: sequences`changeInputValue`\n },\n class MyComponent extends React.Component {\n componentDidMount() {\n this.props.reaction(\n 'focusUsername',\n {\n error: state`usernameError`\n },\n ({ error }) => error && this.input.focus()\n )\n }\n render() {\n return (\n <input\n ref={(node) => {\n this.input = node\n }}\n value={this.props.inputValue}\n onChange={(event) =>\n this.props.changeInputValue({ value: event.target.value })\n }\n />\n )\n }\n }\n)\n```\n\nThese reactions are destroyed when the view is unmounted.\n\n```marksy\n<Info>\nAlso the view reaction receives the **get** property allowing you to grab arbitrary state etc.\n\nA reaction can also depend on a computed, allowing you to react to computed updates.\n</Info>\n```\n","title":"Reactions"},"structure":{"raw":"# Structure\n\nYou can structure your application however you want, but there is a recommended approach based on common experiences building Cerebral applications.\n\n## File structure\n\n```js\nsrc/\n main/\n modules/\n ...\n actions.js\n factories.js\n sequences.js\n providers.js\n reactions.js\n errors.js\n index.js\n controller.js\n```\n\nThis structure favors a single file for each type of composable piece of logic. The root module is named **main** and will hold submodules in the **modules** folder, where each module has the same structure. You will of course not create all these files for every module, only those needed.\n\n## Actions\n\n```js\nexport function actionA({ store }) {\n store.set('foo', 'bar')\n}\n\nexport function actionB({ store }) {\n store.set('foo', 'bar')\n}\n```\n\nYou export multiple actions from each modules *actions.js* file.\n\nIf you prefer arrow functions, you can write:\n\n```js\nexport const actionA = ({ store }) => store.set('foo', 'bar')\n\nexport const actionB = ({ store }) => store.set('foo', 'bar')\n```\n\n## Factories\n\nFactories are similar to actions:\n\n```js\n// Normal function\nexport function setLoadingApp (isLoading) {\n return function setLoadingApp({ store }) {\n store.set('isLoading', isLoading)\n }\n}\n\n// Arrow function\n// We return a named function for debugging purposes\nexport const setLoadingApp = (isLoading) =>\n function setLoadingApp({ store }) {\n store.set('isLoading', isLoading)\n }\n```\n\n## Sequences\n\nYou import all actions and factories into the *sequences.js* file. This will give you autosuggestions on available actions and factories. You can combine this with factories from Cerebral:\n\n```js\nimport { set } from 'cerebral/factories'\nimport { state } from 'cerebral'\nimport * as actions from './actions'\nimport * as factories from './factories'\n\nexport const initialize = [\n factories.setLoadingApp(true),\n actions.getUser,\n actions.setUser,\n set(state`isLoading`, false)\n]\n```\n\n## Modules\n\nYou import all your files into the *index.js* file, attaching them like this:\n\n```js\nimport { Module } from 'cerebral'\nimport * as sequences from './sequences'\nimport * as errors from './errors'\nimport * as computed from './computeds'\nimport * as providers from './providers'\nimport * as reactions from './reactions'\n\nexport default Module({\n state: {\n isLoading: false\n },\n sequences,\n reactions,\n providers,\n catch: [[errors.AuthError, sequences`catchAuthError`]]\n})\n```\n","title":"Structure"},"test":{"raw":"# Test\n\n## Snapshot testing\n\nSnapshot testing allows you to use the Cerebral debugger to create your tests. Just trigger a signal in your application, select it in the debugger and click \"Create signal test\". The test will now run the signal as normal with mocked providers. Any provider usage and mutations related to the original signal execution is handled by the test.\n\n[Read more in the API section](/docs/api/test)\n\n## Traditional assertion\n\nYou can also use a more traditional approach where you assert signal execution.\n\n[Read more in the API section](/docs/api/test)\n","title":"Test"},"typescript":{"raw":"# Typescript\n\n**IMPORTANT** Even though Cerebral does support Typescript it is recommended that you rather look at Cerebrals successor, [Overmind](https://overmindjs.org). It builds upon Cerebral, but is written in Typescript with modern JavaScript features.\n\nCerebral supports full type safety in your application. It is recommended to use [React](https://reactjs.org/) as you will continue to use the types there. You can gradually add type safety to Cerebral so let us take this step by step. You can stop at any step you want when you feel you have enough type safety in your application.\n\n\n## Required: Preparing typing\n\nCerebral uses its proxy concept to type your state and signals. To attach the types to these proxies you will need to create a file called **app.cerebral.ts**:\n\n```marksy\n<Info>\nIs is required that you use the [babel-plugin-cerebral](https://www.npmjs.com/package/babel-plugin-cerebral) package. This package converts the typed proxies into tags.\n</Info>\n```\n\n```ts\nimport * as cerebral from 'cerebral'\n\ntype State = {}\n\nexport const props = cerebral.props\nexport const state = cerebral.state as State\nexport const sequences = cerebral.sequences\nexport const moduleState = cerebral.moduleState\nexport const moduleComputed = cerebral.moduleComputed\nexport const moduleSequences = cerebral.moduleSequences\n```\n\nIn your **tsconfig.json** file it is recommended to add paths so that you can import this file more easily:\n\n```js\n{\n \"compilerOptions\": {\n \"module\": \"es2015\",\n \"target\": \"es5\",\n \"jsx\": \"react\",\n \"lib\": [\"es6\", \"dom\"],\n \"baseUrl\": \"./src\",\n \"paths\": {\n \"app.cerebral\": [\"app.cerebral.ts\"]\n }\n },\n \"exclude\": [\n \"node_modules\"\n ]\n}\n```\n\n## Step1: Typing state\n\nTypically you want to create a **types.ts** file next to your modules. This is where you will define your types in general.\n\n*main/types.ts*\n\n```ts\nexport type State = {\n title: string\n isAwesome: true\n}\n```\n\n```marksy\n<Info>\nThe way we type **sequences** and **computed** just exposes the way they are defined. Meaning if you add new computeds and/or sequences they will automatically be typed.\n</Info>\n```\n\nThis type can now be used in your module to ensure type safety:\n\n*main/index.ts*\n\n```ts\nimport { ModuleDefinition } from 'cerebral'\nimport { State } from './types'\nimport * as sequences from './sequences'\nimport * as computeds from './computeds'\nimport * as providers from './providers'\n\nconst state: State = {\n title: 'My project',\n isAwesome: computeds.isAwesome\n}\n\nconst module: ModuleDefinition = {\n state,\n sequences,\n computeds,\n providers\n}\n\nexport default module\n```\n\nWhere the computed is defined as:\n\n```ts\nimport { state, Compute } from 'cerebral'\n\nexport const isAwesome = Compute(get => get(state.isAwesome) + '!!!')\n```\n\nIn your **app.cerebral** file you can now compose state from all your modules:\n\n```ts\nimport * as cerebral from 'cerebral'\nimport * as Main from './main/types'\nimport * as ModuleA from './main/modules/moduleA/types'\n\ntype State = Main.State & {\n moduleA: ModuleA.State\n}\n\nexport const props = cerebral.props\nexport const state = cerebral.state as State\nexport const sequences = cerebral.sequences\nexport const moduleState = cerebral.moduleState\nexport const moduleComputed = cerebral.moduleComputed\nexport const moduleSequences = cerebral.moduleSequences\n```\n\nSince the module type of proxies depends on what module you use them with you need to cast them where they are used:\n\n*main/sequences.ts*\n```ts\nimport { moduleState as moduleStateProxy } from 'app.cerebral'\nimport { State } from './types'\n\nconst moduleState = moduleStateProxy as State\n```\n\n## Step2: Typing sequences (declarative)\n\nThe most important and common typing that helps you is \"how to execute a sequence\". By defining all your sequences using the **sequence** or **parallel** factory gives you this typing:\n\n```ts\nimport { sequence } from 'cerebral/factories'\n\nexport const mySequence = sequence(actions.myAction)\n\nexport const myOtherSequence = sequence([\n actions.someAction,\n actions.someOtherAction\n])\n```\n\nTo type a sequence with props to pass in, just add it:\n\n```ts\nimport { sequence } from 'cerebral'\n\nexport const mySequence = sequence<{ foo: string }>(actions.myAction)\n```\n\nNow your components will get type information on how to call the sequences. You are now also free to use all the factories with state typing.\n\n```marksy\n<Warning>\nThis approach does **NOT** give you suggestions and type safety on props. This is just impossible to do with this syntax. That said, the value of keeping the declarativeness, typing the input to the sequence and with the assistance of the debugger this is the recommended approach.\n</Warning>\n```\n\n*main/types.ts*\n\n```ts\nimport * as sequences from './sequences'\n\nexport type State = {\n title: string\n isAwesome: true\n}\n\nexport type Sequences = { [key in keyof typeof sequences]: typeof sequences[key] }\n```\n\n## Step3: Typing components\n\nIn Cerebral we recommend using React if you intend to type your components. The typing can be inferred automatically, but it is recommended to split your **connect** and the component:\n\n### With dependencies\n```ts\nimport { state, computed, sequences } from 'app.cerebral'\nimport { connect, ConnectedProps } from '@cerebral/react'\n\nconst deps = {\n foo: state.foo,\n bar: computed.bar,\n onClick: sequences.onClick\n}\n\nexport const MyComponent: React.SFC<typeof deps & ConnectedProps> = ({ foo, bar, onClick }) => {\n return ...\n}\n\nexport default connect(deps, MyComponent)\n```\n\nThis approach allows you to export your components for testing without connecting them. It also writes out better in the different scenarios as you will see soon.\n\n**Using classes:**\n\n```ts\nimport { state, computed, sequences } from 'app.cerebral'\nimport { connect, ConnectedProps } from '@cerebral/react'\n\nconst deps = {\n foo: state.foo,\n bar: computed.bar,\n onClick: sequences.onClick\n}\n\nclass MyComponent extends React.Component<typeof deps & ConnectedProps> {\n render () {\n return null\n }\n}\n\nexport default connect(deps, MyComponent)\n```\n\n### With dependencies and external props\n\nIf the component receives external props you need to type those and your dependencies:\n\n```ts\nimport { state, computed, sequences } from 'app.cerebral'\nimport { connect, ConnectedProps } from '@cerebral/react'\n\ntype Props = {\n external: string\n}\n\nconst deps = {\n foo: state.foo,\n bar: computed.bar,\n onClick: sequences.onClick\n}\n\nexport const MyComponent: React.SFC<Props & typeof deps & ConnectedProps> = ({\n external,\n foo,\n bar,\n onClick\n}) => {\n return ...\n}\n\nexport default connect<Props>(deps, MyComponent)\n```\n\n**And with a class:**\n\n```ts\nimport { state, computed, sequences } from 'app.cerebral'\nimport { connect, ConnectedProps } from '@cerebral/react'\n\ntype Props = {\n external: string\n}\n\nconst deps = {\n foo: state.foo,\n bar: computed.bar,\n onClick: sequences.onClick\n}\n\nclass MyComponent extends React.Component<Props & typeof deps & ConnectedProps> {\n render () {\n return null\n }\n}\n\nexport default connect<Props>(deps, MyComponent)\n```\n\n### Dynamic dependencies\n\nIf you choose the dynamic approach there is no need to type the dependencies, though you have to type the connected props:\n\n```ts\nimport { state, computed, sequences } from 'app.cerebral'\nimport { connect, ConnectedProps } from '@cerebral/react'\n\nconst MyComponent: React.SFC<ConnectedProps> = ({ get }) => {\n const foo = get(state.foo)\n const bar = get(computed.bar)\n const onClick = get(sequences.onClick)\n}\n\nexport default connect(MyComponent)\n```\n\n**And classes:**\n\n```ts\nimport { state, computed, sequences } from 'app.cerebral'\nimport { connect, ConnectedProps } from '@cerebral/react'\n\nclass MyComponent extends React.Component<ConnectedProps> {\n render () {\n const { get } = this.props\n const foo = get(state.foo)\n const bar = get(computed.bar)\n const onClick = get(sequences.onClick)\n }\n}\n\nexport default connect(MyComponent)\n```\n\n### Dynamic dependencies and external props\n\n```ts\nimport { state, computed, sequences } from 'app.cerebral'\nimport { connect, ConnectedProps } from '@cerebral/react'\n\ntype Props = {\n external: string\n}\n\nconst MyComponent: React.SFC<Props & ConnectedProps> = ({ external, get }) => {\n const foo = get(state.foo)\n const bar = get(computed.bar)\n const onClick = get(sequences.onClick)\n}\n\nexport default connect<Props>(MyComponent)\n```\n\n**And classes:**\n\n```ts\nimport { state, computed, sequences } from 'app.cerebral'\nimport { connect, ConnectedProps } from '@cerebral/react'\n\ntype Props = {\n external: string\n}\n\nclass MyComponent extends React.Component<Props & ConnectedProps> {\n render () {\n const { get, external } = this.props\n const foo = get(state.foo)\n const bar = get(computed.bar)\n const onClick = get(sequences.onClick)\n }\n}\n```\n\n## Step4: Typing actions and providers\n\nWhen writing actions you access the context. The default context is already typed and you can add your own provider typings.\n\n*main/providers.ts*\n```ts\nexport const myProvider = {\n get(value: string) {\n return value\n }\n}\n```\n\n*main/types.ts*\n\n```ts\nimport * as computeds from './computeds'\nimport * as sequences from './sequences'\nimport * as providers from './providers'\n\nexport type State = {\n title: string\n isAwesome: true\n}\n\nexport type Compute = { [key in keyof typeof computed]: typeof computed[key] }\n\nexport type Sequences = { [key in keyof typeof sequences]: typeof sequences[key] }\n\nexport type Providers = { [key in keyof typeof providers]: typeof providers[key] }\n```\n\n```ts\nimport * as cerebral from 'cerebral'\nimport * as Main from './main/types'\n\ntype State = Main.State\n\ntype Sequences = Main.Sequences\n\ntype Compute = Main.Compute\n\ntype Providers = Main.Providers\n\nexport type Context = cerebral.IContext<{}> & Providers\n\nexport const props = cerebral.props\nexport const state = cerebral.state as State\nexport const computed = cerebral.computed as Compute\nexport const sequences = cerebral.sequences as Sequences\nexport const moduleState = cerebral.moduleState\nexport const moduleComputed = cerebral.moduleComputed\nexport const moduleSequences = cerebral.moduleSequences\n```\n\nWhen you now create your actions you can attach a context type:\n\n```ts\nimport { Context } from 'app.cerebral'\n\nexport const function myAction ({ store, myProvider }: Context) {\n\n}\n```\n\n## Step5: Typing sequences (chain)\n\nTo get full type safety in sequences you will need to move to a less declarative chaining api. But the cost gives you the value of full type safety. Note that we are also updating the Context typings here:\n\n```ts\nimport * as cerebral from 'cerebral'\nimport * as Main from './main/types'\n\ntype State = Main.State\n\ntype Sequences = Main.Sequences\n\ntype Compute = Main.Compute\n\ntype Providers = Main.Providers\n\nexport type Context<Props = {}> = cerebral.IContext<Props> & Providers\n\nexport type BranchContext<Paths, Props = {}> = cerebral.IBranchContext<Paths, Props> &\n Providers\n\nexport const props = cerebral.props\nexport const Sequence = cerebral.ChainSequenceFactory<Context>()\nexport const SequenceWithProps = cerebral.ChainSequenceWithPropsFactory<Context>()\nexport const state = cerebral.state as State\nexport const computed = cerebral.computed as Compute\nexport const sequences = cerebral.sequences as Sequences\nexport const moduleState = cerebral.moduleState\nexport const moduleComputed = cerebral.moduleComputed\nexport const moduleSequences = cerebral.moduleSequences\n```\n\nWhen you now define your sequences you will use the exported **Sequence** and **SequenceWithProps** from the **app.cerebral** file:\n\n```ts\nimport { Sequence, SequenceWithProps, state } from 'app.cerebral'\nimport * as actions from './actions'\n\nexport const doThis = Sequence((sequence) =>\n sequence\n .action(actions.doSomething)\n .action('doSomethingElse', ({ store }) =>\n store.set(state.foo, 'bar')\n )\n)\n\nexport const doThat = SequenceWithProps<{ foo: string }>((sequence) =>\n sequence.action('doThisThing', ({ store, props }) =>\n store.set(state.foo, props.foo)\n )\n)\n```\n\n```marksy\n<Info>\nComposing together actions like this will infer what props are available as they are returned from actions and made available to the sequence. Even complete sequences can be composed into another sequence and TypeScript will yell at you if it does not match.\n</Info>\n```\n\nTo run conditional logic you will branch out:\n\n```ts\nimport { Sequence, state } from 'app.cerebral'\nimport * as actions from './actions'\n\nexport const doThis = Sequence((sequence) => sequence\n .branch(actions.doOneOrTheOther)\n .paths({\n one: (sequence) => sequence,\n other: (sequence) => sequence\n })\n)\n```\n\nYou compose in sequences by:\n\n```ts\nimport { Sequence, state } from 'app.cerebral'\nimport * as actions from './actions'\n\nexport const doThis = Sequence((sequence) => sequence\n .sequence(sequences.someOtherSequence)\n .parallel([sequences.sequenceA, sequences.sequenceB])\n)\n```\n\nThe flow factories are implemented as part of the chaining API:\n\n```ts\nimport { Sequence, state } from 'app.cerebral'\nimport * as actions from './actions'\n\nexport const doThis = Sequence((sequence) =>\n sequence\n .delay(1000)\n .when(state.foo)\n .paths({\n true: (sequence) => sequence,\n false: (sequence) => sequence\n })\n)\n```\n\nWith the new action typings you will be able to improve inference in the sequences by:\n\n```ts\nimport { Context } from 'app.cerebral'\n\nexport const function myAction ({ store, myProvider }: Context) {\n\n}\n\nexport const function myAction ({ store, myProvider, props }: Context<{ foo: string }>) {\n\n}\n```\n\nAnd if the action triggers a path:\n\n```ts\nimport { BranchContext } from 'app.cerebral'\n\nexport const function myAction ({ store, myProvider, path }: BranchContext<\n {\n success: { foo: string },\n error: { error: string }\n }\n>) {\n\n}\n\nexport const function myAction ({ store, myProvider, path }: BranchContext<\n {\n success: { foo: string },\n error: { error: string }\n },\n {\n someProp: number\n }\n>) {\n\n}\n```\n","title":"Typescript"}},"views":{"index":{"raw":"# @cerebral/angular\n\n[Angular](https://angular.io/) view for Cerebral.\n\n## Install\n\n`npm install @cerebral/angular @angular/core @angular/platform-browser babel-plugin-transform-decorators-legacy`\n\n## CerebralService\n\nThe Cerebral service exposes the Cerebral controller to your application.\n\n```ts\nimport { NgModule } from '@angular/core'\nimport { BrowserModule } from '@angular/platform-browser'\n\nimport { provide } from 'cerebral'\nimport { AppService } from '@cerebral/angular'\n\nimport { AppComponent } from './app.component.ts'\nimport { SomeAngularService } from './SomeAngularService'\n\n// Create a factory to instantiate Cerebral. It can receive\n// dependencies which you can \"provide\" to Cerebral to be used\n// within sequences\nexport function configureApp(someAngularService : SomeAngularService) {\n return new AppService({\n // We use the \"provide\" function to an angular service to the sequences\n // of Cerebral\n providers: [\n provide('someAngularService', someAngularService)\n ]\n })\n})\n\n@NgModule({\n imports: [ BrowserModule ],\n declarations: [ AppComponent ],\n bootstrap: [ AppComponent ],\n providers: [\n {\n provide: AppService,\n useFactory: configureApp,\n deps: [SomeAngularService]\n },\n ]\n})\nexport class AppModule {}\n```\n\n## connect decorator\n\nThe connect decorator connects state and signals to your components.\n\n```ts\nimport {\n Component,\n ChangeDetectionStrategy,\n ChangeDetectorRef\n} from '@angular/core'\nimport { sequences, state } from 'cerebral/tags'\nimport {\n connect,\n AppService,\n CerebralComponent\n} from '@cerebral/angular'\n\n@Component({\n selector: 'app-component',\n template: `\n <div (click)=\"onClick()\">{{foo}}</div>\n `,\n // Change detection needs to be set to \"OnPush\"\n changeDetection: ChangeDetectionStrategy.OnPush\n})\n@connect({\n // For AOT to work you will have to use the array version of template\n // tags\n myName: state(['foo']),\n onClick: sequences(['clicked'])\n})\nexport class AppComponent extends CerebralComponent {\n // You have to inject \"ChangeDetectionRef\" and \"ControllerService\" and pass\n // them to parent for connect to do its work\n constructor(cdr: ChangeDetectorRef, app: AppService) {\n super(cdr, app)\n app.getSequence('onClick')()\n }\n}\n```\n","title":"@cerebral/angular"},"angularjs":{"raw":"# @cerebral/angularjs\n\n[Angularjs](https://angularjs.org) view for Cerebral.\n\n## Install\n\n`npm install @cerebral/angularjs angular`\n\n## Config\n\n```js\nimport angular from 'angular'\nimport { addModule, connect } from '@cerebral/angularjs'\nimport App from 'cerebral'\n\naddModule(angular)\n\nconst mainModule = Module({\n state: {\n foo: 'bar'\n },\n sequences: {\n onClick: []\n },\n services: ['MyAngularService'] // main module only. Added as providers with same name\n})\n\nconst app = App(mainModule)\n\nangular.module('app', ['cerebral'])\n .config(function (cerebralProvider) {\n cerebralProvider.configure(app)\n })\n ...\n```\n\n## connect\n\n```js\nimport angular from 'angular'\nimport { addModule, connect } from '@cerebral/angularjs'\nimport { state, sequences } from 'cerebral'\n\nangular.module('app', ['cerebral'])\n .config(...)\n .component('myComponent', {\n template: '<div ng-click=\"$ctrl.click()\">{{$ctrl.foo}}</div>',\n controller: connect({\n foo: state`foo`,\n click: sequences`onClick`\n }, 'MyComponent', ['cerebral', function MyController (cerebral) {\n\n // In some cases you might need access to the cerebral app.\n // You can inject the cerebral angular service and\n // access it's app property anywhere in your app\n cerebral.app.getSequence('mySignal')()\n\n // Optionally add custom behaviour to app\n }])\n })\n```\n\nSince angular doesn't expose the component name,\nyou will need to provide one to `connect` for the\ncomponent to be given a name in cerebral.\n\nYou can call connect in the following ways:\n\n```js\nconnect(dependencies)\nconnect(dependencies, name)\nconnect(dependencies, controller)\nconnect(dependencies, name, controller)\n```\n","title":"@cerebral/angularjs"},"inferno":{"raw":"# @cerebral/inferno\n\n[Inferno](http://infernojs.org) view for Cerebral.\n\n## Install\n\n`npm install @cerebral/inferno inferno babel-plugin-inferno`\n\n## Container\n\n```js\nimport { render } from 'inferno'\nimport App from 'cerebral'\nimport { Container } from '@cerebral/inferno'\nimport AppComponent from './components/App'\nimport main from './main'\n\nconst app = App(main)\n\nrender(\n <Container app={app}>\n <App />\n </Container>,\n document.querySelector('#app')\n)\n```\n\n## connect\n\n```js\nimport { Component } from 'inferno'\nimport { connect } from '@cerebral/inferno'\nimport { state, sequences } from 'cerebral'\n\n// Stateless\nexport default connect(\n {\n foo: state`foo`,\n onClick: sequences`onClick`\n },\n function MyComponent ({foo, onClick}) {\n return <div onClick={() => onClick()}>{foo}</div>\n }\n)\n\n// Stateful\nexport default connect(\n {\n foo: state.foo,\n onClick: sequences.onClick\n },\n class MyComponent extends Component {\n render () {\n return <div onClick={() => this.props.onClick()}>{this.props.foo}</div>\n }\n }\n)\n```\n","title":"@cerebral/inferno"},"preact":{"raw":"# @cerebral/preact\n\n[Preact](https://github.com/developit/preact) view for Cerebral.\n\n## Install\n\n`npm install @cerebral/preact preact babel-preset-preact`\n\n## Container\n\n```js\nimport { h, render } from 'preact'\nimport App from 'cerebral'\nimport { Container } from '@cerebral/preact'\nimport AppComponent from './components/AppComponent'\nimport main from './main'\n\nconst app = App(main)\n\nrender(\n <Container app={app}>\n <App />\n </Container>,\n document.querySelector('#app')\n)\n```\n\n## connect\n\n```js\nimport { h, Component } from 'preact'\nimport { connect } from '@cerebral/preact'\nimport { state, sequences } from 'cerebral'\n\nexport default connect(\n {\n foo: state`foo`,\n onClick: sequences`onClick`\n },\n class MyComponent extends Component {\n render({ foo, click }) {\n return <div onClick={() => onClick()}>{foo}</div>\n }\n }\n)\n```\n","title":"@cerebral/preact"},"react":{"raw":"# @cerebral/react\n\n[React](https://facebook.github.io/react) view for Cerebral.\n\n## Install\n\n`npm install @cerebral/react react react-dom babel-preset-react`\n\n## Container\n\n```js\nimport React from 'react'\nimport { render } from 'react-dom'\nimport App from 'cerebral'\nimport { Container } from '@cerebral/react'\nimport AppComponent from './components/App'\nimport main from './main'\n\nconst app = App(main)\n\nrender(\n <Container app={app}>\n <AppComponent />\n </Container>,\n document.querySelector('#app')\n)\n```\n\n## connect\n\nTypically you add a stateless component:\n\n```js\nimport React from 'react'\nimport { state, sequences } from 'cerebral'\nimport { connect } from '@cerebral/react'\n\nexport default connect(\n {\n foo: state`foo`,\n onClick: sequences`onClick`\n },\n function MyComponent({ foo, onClick }) {\n return <div onClick={() => onClick()}>{foo}</div>\n }\n)\n```\n\nBut you can also use stateful components:\n\n```js\nimport React from 'react'\nimport { state, sequences } from 'cerebral'\nimport { connect } from '@cerebral/react'\n\nexport default connect(\n {\n foo: state`foo`,\n onClick: sequences`onClick`\n },\n class MyComponent extends React.Component {\n render() {\n return <div onClick={() => this.props.onClick()}>{this.props.foo}</div>\n }\n }\n)\n```\n\nYou do not have to define dependencies right away, you can rather dynamically grab them from inside the component. This is a preference thing:\n\n```js\nimport React from 'react'\nimport { state, sequences } from 'cerebral'\nimport { connect } from '@cerebral/react'\n\nexport default connect(\n function MyComponent({ get }) {\n const foo = get(state`foo`)\n const onClick = get(sequences`onClick`)\n\n return <div onClick={() => onClick()}>{foo}</div>\n }\n)\n```\n\nYou can add an additional function to connect that gives you full control of properties of the component and dependencies. The returned object from this function will be the exact props passed into the component.\n\n```js\nimport React from 'react'\nimport { sequences, state } from 'cerebral'\nimport { connect } from '@cerebral/react'\n\nexport default connect(\n {\n foo: state`app.foo`,\n onClick: sequences`app.onClick`\n },\n ({ foo, onClick }, ownProps, get) => {\n return {\n // values from state could be transformed here\n foo: `Label: ${foo}`,\n // sequence calls could be bound here, so component uses it as general callback\n onClick: (e) => onClick({ id: ownProps.id })\n }\n },\n function App({ foo, onClick }) {\n return <div onClick={onClick}>{foo}</div>\n }\n)\n```\n\n* **dependencyProps** are the props you connected.\n\n* **ownProps** are the props passed into the component by the parent.\n\n* **get** allows you to resolve computed etc., just like get in actions.\n\n## TypeScript\n\nIf you use TypeScript, you can type your component props with connect. Read the [advanced section](/docs/advanced/typescript) on how to do this.\n","title":"@cerebral/react"},"vue":{"raw":"# @cerebral/vue\n\n[Vue.js](https://vuejs.org) view for Cerebral.\n\n## Install\n\n`npm install @cerebral/vue vue`\n\n## Container\n\n```js\nimport Vue from 'vue/dist/vue'\nimport App from 'cerebral'\nimport { Container, connect } from '@cerebral/vue'\nimport main from './main'\n\nconst app = App(main)\n\nnew Vue({\n render: h =>\n h({\n components: {\n Container: Container(app),\n AppComponent: AppComponent\n },\n template: \"<Container><AppComponent></AppComponent></Container>\"\n })\n}).$mount(\"#app\");\n```\n\n## connect\n\n_MyComponent.js_\n\n```js\nimport { connect } from '@cerebral/vue'\nimport { state, sequence } from 'cerebral'\n\nexport default connect(\n {\n foo: state`foo`,\n click: sequence`clicked`\n },\n {\n template: '<div v-on:click=\"click()\">{{foo}}</div>'\n }\n)\n```\n\n_main.js_\n\n```js\nimport Vue from 'vue/dist/vue'\nimport App from 'cerebral'\nimport { Container, connect } from '@cerebral/vue'\nimport MyComponent from './MyComponent'\nimport main from './main'\n\nconst app = App(main)\n\nvar vue = new Vue({\n el: '#app',\n components: {\n container: Container(app),\n 'my-component': MyComponent\n }\n})\n```\n","title":"@cerebral/vue"}},"guides":{"index":{"raw":"# Http\n\nMost applications needs some sort of requests going to a server. With Cerebral you choose your favourite library and expose it as a provider. By exposing it as a provider Cerebral will be able to track its usage and you can be more specific about how the library should work for your application.\n\n## Using axios\n\n[Axios documentation](https://www.npmjs.com/package/axios)\n\n```js\nimport axios from 'axios'\n\nexport const http = {\n get: axios.get,\n post: axios.post,\n put: axios.put,\n patch: axios.patch,\n delete: axios.delete\n}\n```\n\nIn this scenario we are just exposing the library methods we are going to use in our application, that might be enough. Or maybe you want to have an additional custom request, which is what the default export of axios provides:\n\n```js\nimport axios from 'axios'\n\nexport const http = {\n request: axios,\n get: axios.get,\n post: axios.post,\n put: axios.put,\n patch: axios.patch,\n delete: axios.delete\n}\n```\n\nYou might want to intercept the usage to include a default header:\n\n```js\nimport axios from 'axios'\n\nfunction withDefaultHeaders (config) {\n return {\n ...config,\n headers: {\n ...config.headers || {},\n 'my special header': 'awesome'\n }\n }\n}\n\nexport const http = {\n request(config) {\n return axios(withDefaultHeaders(config)) \n },\n get(url, config) {\n return axios.get(url, withDefaultHeaders(config))\n },\n post(url, data, config) {\n return axios.post(url, data, withDefaultHeaders(config))\n },\n ...\n}\n```\n\nAnd maybe this should be a token you want to set when the application loads:\n\n```js\nimport axios from 'axios'\n\nlet token\n\nfunction withDefaultHeaders (config) {\n return {\n ...config,\n headers: {\n ...config.headers || {},\n 'Authorization': `bearer ${token}`\n }\n }\n}\n\nexport const http = {\n setToken(newToken) {\n token = newToken\n }\n request(config) {\n return axios(withDefaultHeaders(config)) \n },\n get(url, config) {\n return axios.get(url, withDefaultHeaders(config))\n },\n post(url, data, config) {\n return axios.post(url, data, withDefaultHeaders(config))\n },\n ...\n}\n```\n\nThough this token might be from local storage. Lets say you have a provider to talk to local storage and you just grab the token from there. This is another good example, cause you very likely want to JSON stringify/parse data in your local storage:\n\n```js\nimport axios from 'axios'\n\nexport const localStorage = {\n get(key) {\n return JSON.parse(localStorage.getItem(key))\n },\n set(key, value) {\n localStorage.setItem(key, JSON.stringify(value))\n }\n}\n\n// We use an IIFE to encapsulate our provider\nexport const http = (() => {\n function withDefaultHeaders (config, token) {\n return {\n ...config,\n headers: {\n ...config.headers || {},\n 'Authorization': `bearer ${token}`\n }\n }\n }\n\n return {\n request(config) {\n const token = this.context.localStorage.get('token')\n return axios(withDefaultHeaders(config, token)) \n },\n get(url, config) {\n const token = this.context.localStorage.get('token')\n return axios.get(url, withDefaultHeaders(config, token))\n },\n post(url, data, config) {\n const token = this.context.localStorage.get('token')\n return axios.post(url, data, withDefaultHeaders(config, token))\n },\n ...\n }\n})()\n```\n\nAs you can see there are many ways to put a provider together. It totally depends on your application what makes sense. What to also take note of here is that **http** could be completely replaced with a new provider exposing the same API.\n\n## Using fetch\n\nWe could also just use the native fetch implementation to create our provider. Let us keep the signature and replace the code:\n\n```js\nimport axios from 'axios'\n\nexport const localStorage = {\n get(key) {\n return JSON.parse(localStorage.getItem(key))\n },\n set(key, value) {\n localStorage.setItem(key, JSON.stringify(value))\n }\n}\n\n// We use an IIFE to encapsulate our provider\nexport const http = (() => {\n function withDefaultHeaders (config, token) {\n return {\n ...config,\n headers: {\n ...config.headers || {},\n 'Content-Type': 'application/json',\n 'Authorization': `bearer ${token}`\n }\n }\n }\n\n function evaluateResponse (response) {\n if (response.status >= 200 && response.status < 300) {\n return response.toJSON()\n }\n\n return Promise.reject(response)\n }\n\n return {\n request(config = {}) {\n const token = this.context.localStorage.get('token')\n return fetch(config.url, withDefaultHeaders(config, token))\n .then(evaluateResponse)\n },\n get(url, config = {}) {\n const token = this.context.localStorage.get('token')\n config.url = url\n return fetch(url, withDefaultHeaders(config, token))\n .then(evaluateResponse)\n\n },\n post(url, data, config = {}) {\n const token = this.context.localStorage.get('token')\n config.url = url\n config.method = 'POST'\n config.body = JSON.stringify(data)\n\n return fetch(url, withDefaultHeaders(config, token))\n .then(evaluateResponse)\n },\n ...\n }\n})()\n```\n\nNow our application works the same way, but we replaced the tool that performs the logic. This gives you a lot of flexibility in how you want to deal with requests.\n\n## Specific API\n\nYou could also be more specific about how we expose running requests from your application. We could simply replace the signature to:\n\n```js\nimport qs from 'query-string'\n\nexport const api = (() => {\n const baseUrl = '/api'\n const http = {\n get (url, query = {}) {\n const queryString = qs.stringify(query)\n return fetch(baseUrl + url + (queryString ? '?' + queryString : '')\n .then(response => response.toJSON())\n }\n }\n\n return {\n getUser (id) {\n return http.get(`/users/${id}`)\n },\n getItems (query) {\n return http.get(`/items`, query)\n },\n getItem (id) {\n return http.get(`/items/${id}`)\n }\n }\n})()\n```\n\nThis approach gives you a more specific API in your actual application.","title":"Http"},"routing":{"raw":"# Routing\n\nThere are two different way to do routing. You can do the routing inside your view layer or you can treat url changes like any other event in your application. In this guide we will look at how you can do a \"Cerebral first\" approach to routing, but also generally about how to compose sequences to manage routing.\n\n## Cerebral first router\n\nBy installing [page.js](https://www.npmjs.com/package/page) you can implement a router that triggers a sequence when the url changes. This can be done making your main module a module factory:\n\n```js\nimport page from 'page'\nimport { routeToRoot, routeToItems, routeToItem } from './sequences'\n\nexport default ({ app }) => {\n\n // We want to start the router when the app is initialized\n app.on('initialized', () => page.start())\n\n // We create a route factory which takes the route url and\n // the sequences that should run when it triggers. It does two things\n // \n // 1. It register the route to page.js which runs the sequence using the\n // path as the name of the execution, the sequence and passes in any\n // params\n // \n // 2. It returns an action that you can run from your views, mapping\n // the \"props.params\" passed in into the related url. Then triggers\n // the url\n function route(url, sequence) {\n page(url, ({ path, params }) => app.runSequence(path, sequence, { params }))\n\n return ({ props }) => {\n const urlWithReplacedParams = Object.keys(props.params || {}).reduce((currentUrl, param) => {\n return currentUrl.replace(`:${param}`, props.params[param])\n }, url)\n\n page.show(urlWithReplacedParams)\n }\n }\n\n return {\n sequences: {\n routeToRoot: route('/', routeToRoot),\n routeToItems: route('/items', routeToItems),\n routeToItem: route('/items/:id', routeToItem)\n }\n }\n}\n```\n\nWith this approach you trigger url changes with hyperlinks or you can call the sequences directly, which redirects to the url in question.\n\n```js\nimport { connect } from '@cerebral/react'\nimport { sequences } from 'cerebral'\n\nexport default connect(\n function MyComponent ({ get }) {\n const routeToItem = get(sequences.routeToItem)\n\n return (\n <button\n onClick={() => routeToItem({ params: { id: 123 }})}\n >\n Go to 123\n </button>\n )\n }\n)\n```\n\n## Query strings\n\nNot all applications has query strings, but if you need them you can easily add them by `npm install query-string`. There are several ways to manage this and in this example we will add another prop that has the parsed query string:\n\n```js\nimport page from 'page'\nimport qs from 'query-string'\nimport { routeToRoot, routeToItems, routeToItem } from './sequences'\n\nexport default ({ app }) => {\n\n app.on('initialized', () => page.start())\n\n function route(url, sequence) {\n page(url, ({ path, params, querystring }) => {\n // We parse the querystring passed in by page.js and pass it to the sequence\n // on the \"query\" prop\n const query = qs.parse(querystring)\n\n app.runSequence(path, sequence, { params, query })\n })\n\n return ({ props }) => {\n const urlWithReplacedParams = Object.keys(props.params || {}).reduce((currentUrl, param) => {\n return currentUrl.replace(`:${param}`, props.params[param])\n }, url)\n // We stringify any query passed in when the sequence is executed from the\n // view\n const query = props.query ? '?' + qs.stringify(props.query) : ''\n\n page.show(urlWithReplacedParams + query)\n }\n }\n\n return {\n sequences: {\n routeToRoot: route('/', routeToRoot),\n routeToItems: route('/items', routeToItems),\n routeToItem: route('/items/:id', routeToItem)\n }\n }\n}\n```\n\nAgain you just use the query property in a component to add them to the url:\n\n```js\nimport { connect } from '@cerebral/react'\nimport { sequences } from 'cerebral'\n\nexport default connect(\n function MyComponent ({ get }) {\n const routeToItems = get(sequences`routeToItems`)\n\n return (\n <button\n onClick={() => routeToItems({ query: { limit: 10 }})}\n >\n Go to items\n </button>\n )\n }\n)\n```\n\nYou might not want to use a **params** and **query** property, but rather extract props to params first and then any leftover props is put on the query. This requires a bit more code and you are perfectly free to do that. This is also a good start for a module that can be shared with others if you get inspired and want to maintain a Cerebral router!\n\n## Managing nested routes\n\nWhen you have two routes of for example `/items` and `/items/:id` you might want to run the logic for the first route when the second is triggered. The reason can be that you show a page with items and the id is what indicates the modal that should be displayed on top of that list. The two routes are defined separately:\n\n```js\n{\n sequences: {\n routeToRoot: route('/', routeToRoot),\n routeToItems: route('/items', routeToItems),\n routeToItem: route('/items/:id', routeToItem)\n }\n}\n```\n\nThe way we would make sure that the items logic runs as well when `/items/:id` is triggered is just to compose it. In the `sequences.js` file of the module:\n\n```js\nimport { set } from 'cerebral/factories'\nimport { state, props } from 'cerebral'\nimport * as actions from './actions'\n\nexport const routeToRoot = set(state`page`, 'home')\n\nexport const routeToItems = [\n set(state`page`, 'items'),\n actions.getItems,\n set(state`items`, props`items`)\n]\n\nexport const routeToItem = [\n routeToItems, // We just add the sequence\n actions.getItemDetails,\n set(state`itemDetails.${props`id`}`, props`itemDetails`),\n set(state`currentItemId`, props`id`)\n]\n```\n\nIn this situation it will go an grab the items first and then it will go and grab the single item details. We could improve this by running them in parallel:\n\n```js\nimport { parallel, set } from 'cerebral/factories'\nimport { state, props } from 'cerebral'\nimport * as actions from './actions'\n\nexport const routeToRoot = set(state`page`, 'home')\n\nexport const routeToItems = [\n set(state`page`, 'items'),\n actions.getItems,\n set(state`items`, props`items`)\n]\n\nexport const routeToItem = parallel([\n routeToItems,\n [\n actions.getItemDetails,\n set(state`itemDetails.${props`id`}`, props`itemDetails`),\n set(state`currentItemId`, props`id`)\n ]\n])\n```\n\nNow we are instantly setting the page, though the items in the background might be populated after the item details is downloaded and set. How you compose this together most effectively depends on the data and the user experience you want to create. The sequences is a powerful tool to handle these kinds of compositions.","title":"Routing"},"ssr":{"raw":"# Server Side Rendering\n\nServer side rendering is tricky business. There are numerous considerations to take and how you execute on these considerations depends on the application. Cerebral supports server side rendering and in this article we will look at the typical strategies to make this work.\n\n## The flow\n\nWhen you want to deliver content to your users as fast as possible, like with a progressive web app, or you just want to search engine optimize the application, you will need to render the UI on the server and return it on the initial request.\n\nLet us imagine a user going to **www.example.com**. This request goes to the server and it will return some HTML, here showing example with Node express, manually returning the HTML string:\n\n```js\napp.get('/', (req, res) => {\n res.send(`<!DOCTYPE html>\n<html>\n <head></head>\n <body>\n <div id=\"app\"></div>\n <script src=\"/app.js\"></script>\n </body>\n</html>`)\n})\n```\n\nThis response is now displayed in the browser and the Cerebral application is ready to take over and your view library of choice will populate the `<div id=\"app\"></div>` with the HTML of the app.\n\nNow lets lay out the considerations we need to take regarding server side rendering:\n\n1. **Render components** - The minimum requirement is to actually render the components on the server inside the same `<div id=\"app\"></div>` as the client will\n\n2. **Universal Cerebral App** - When your client fires up it might need some initial data from the server to display the content. With the help of the **Universal Cerebral App** we can automate this process\n\n3. **Synchronize with router** - If your application uses the Cerebral router it is not only initial data that possibly needs to be synchronized, but also the state that is related to what URL you are on\n\n## Render components\n\nTo render the components on the server they should be as pure as possible. By default components in a Cerebral app are kept pure because all application logic is contained in sequences and actions. That means it is safe to grab your root component on the server and render it:\n\n```js\nimport App from '../client/components/App'\nimport { renderToString } from 'react-dom/server'\n\napp.get('/', (req, res) => {\n const appHtml = renderToString(<App />)\n\n res.send(`<!DOCTYPE html>\n<html>\n <head></head>\n <body>\n <div id=\"app\">${appHtml}</div>\n <script src=\"/app.js\"></script>\n </body>\n</html>`)\n})\n```\n\nA good workflow for working with server side rendered components requires some packages and configuration. This is one approach to such a setup.\n\n### Run Node with Babel\n\nTo bring your components into Node you should run Node with the [babel-node](https://babeljs.io/docs/usage/cli/#babel-node) project. Make sure this is not run in production though. You will need to build the server files as well.\n\n## Universal Controller\n\nCerebrals universal app allows you to mount your client side initial state on the server, execute logic to change that state and inject it with the server rendered app so that your client does not need to refetch the data.\n\n```js\nimport { UniversalApp } from 'cerebral'\nimport main from '../client/main'\nimport AppComponent from '../client/components/App'\nimport {renderToString} from 'react-dom/server'\n\napp.get('/', (req, res) => {\n const app = UniversalApp(main)\n const appHtml = renderToString(<AppComponent/>)\n\n res.send(`<!DOCTYPE html>\n<html>\n <head></head>\n <body>\n <div id=\"app\">${appHtml}</div>\n <script src=\"/app.js\"></script>\n </body>\n</html>`)\n})\n```\n\nThis means that when the app is rendered it will have the same initial state, both on the client and the server. To actually produce some new state we need to execute logic and we do that using the **run** method:\n\n```js\nimport { UniversalApp, state } from 'cerebral'\nimport main from '../client/main'\nimport AppComponent from '../client/components/App'\nimport {renderToString} from 'react-dom/server'\n\nfunction setInitialState({ store, props }) {\n store.set(state.app.user, props.user)\n}\n\napp.get('/', (req, res) => {\n const app = UniversalApp(main)\n\n db\n .getUser()\n .then((user) => {\n return app.run(setInitialState, { user })\n })\n .then(() => {\n const appHtml = renderToString(\n <Container app={app}>\n <App />\n </Container>\n )\n const stateScript = app.getScript()\n\n res.send(`<!DOCTYPE html>\n<html>\n <head>\n ${stateScript}\n </head>\n <body>\n <div id=\"app\">${appHtml}</div>\n <script src=\"/app.js\"></script>\n </body>\n</html>`)\n })\n})\n```\n\nLets summarize the changes:\n\n1. We create a sequence, which is just one action, that expects to receive a user as a prop. This user is then put into the state\n\n2. Before we start rendering our application we go and grab a user from the database. When this user is fetched we run the app passing in the user, making it available on the props\n\n3. When the execution is done we render the application by using the **Container** component which provides the app to the components\n\n4. Now we can extract the script that contains the exact state changes made. The client will automatically pick up this script and produce the correct initial state of the application\n\n5. We put the script in the head\n\nThis is what you need to do if you want to put the client side application in a different state than the default one. There can be any number of reason for this, but beware... it is not strictly necessary. You might rather want to render your application in a \"skeleton version\" and then fetch the data needed from the client instead.\n\n## Summary\n\nRendering on the server is not straight forward. It depends heavily on the app. Do you do routing, or do you want a skeleton app and do data fetching on client? How beneficial is it to grab state on server and inject it compared to making those requests from the client? There is no one right answer to this. But with Cerebral you have the tools you need to produce state on the server and rehydrate that state on the client, if you want to.\n","title":"Server Side Rendering"}},"api":{"index":{"raw":"# Action\n\nWhen actions run they are passed a context. This context is created by Cerebral for every action run.\n\n```js\nfunction iAmAnAction(context) {}\n```\n\nThe context is populated by Cerebral and you can configure this by creating **providers**. By default Cerebral adds the following providers on the context.\n\n## Props\n\nWhen you trigger a sequence you can pass it a payload. This payload is the starting point of the props to the sequence. Given the sequence:\n\n```js\n[actionA, actionB]\n```\n\n```js\nsomeSequence({\n foo: 'bar'\n})\n```\n\nThe first action will receive the payload passed into the signal.\n\n```js\nfunction actionA({ props }) {\n props // {foo: \"bar\"}\n\n return {\n bar: 'baz'\n }\n}\n```\n\nBy returning a new object the next action will see an extended payload:\n\n```js\nfunction actionB({ props }) {\n props // {foo: \"bar\", bar: \"baz\"}\n}\n```\n\nSo returning an object from actions, either directly or from a promise, extends the payload for later actions to handle.\n\n## Store\n\nTo change the state of your application you use the store API.\n\n```js\nfunction setSomething({ store }) {\n store.set('some.path.foo', 'bar')\n}\n```\n\nAll common state operations are available as a method. Instead of first pointing to a value and then operate, you operate first and give the path to the value.\n\n```js\n// Traditional approach\nsomeArray.push('newItem')\n// With Cerebral\nstore.push('path.to.array', 'newItem')\n```\n\nThis is the one core concept of Cerebral that gives all its power. This simple approach allows for a few important things:\n\n1. Track mutations in the application so that it can be passed to the debugger\n2. Track mutations so that it can optimally inform components about needed renders\n3. No need for immutability or intercepting getters and setters\n\nThe following methods are available:\n\n- **concat**\n- **increment**\n- **merge**\n- **pop**\n- **push**\n- **set**\n- **shift**\n- **splice**\n- **toggle**\n- **unset**\n- **unshift**\n\n## Path\n\nThe path on the context is only available if there is actually expressed a path after the action in question:\n\n```js\nimport * as actions from './actions'\n\nexport default [\n actions.actionA,\n actions.actionB,\n {\n foo: actions.actionC\n }\n]\n```\n\nIn this scenario only *actionB* has the path on its context. That means in any action you can check if path is available and what paths can be taken by looking at its keys.\n\n## Get\n\nYou can grab any tag value by using *get*:\n\n```js\nimport { state } from 'cerebral'\n\nfunction someAction({ get }) {\n const foo = get(state`foo`)\n}\n```\n\n## Resolve\n\n**Get** is actually a wrapper around resolve and you should use that. **Resolve** has some additional functionality though. To resolve an argument passed to a factory you can use resolve:\n\n```js\nfunction someActionFactory(someArgument) {\n function someAction({ resolve }) {\n // The argument can be anything, even plain values\n const value = resolve.value(someArgument)\n }\n\n return someAction\n}\n```\n\nYou can also use resolve to check the value type and extract for example the path of tags:\n\n```js\nfunction someActionFactory(someArgument) {\n function someAction({ resolve }) {\n if (resolve.isTag(someArgument)) {\n const path = resolve.path(someArgument)\n }\n }\n\n return someAction\n}\n```","title":"Action"},"app":{"raw":"# App\n\n```js\nimport App from 'cerebral'\nimport main from './main' // The main module\n\nconst app = App(main, {\n // The devtools\n devtools: null,\n // Also logs error handling to console.\n throwToConsole: true,\n // Prevent rethrow of errors (useful if you already use an on('error') handler)\n noRethrow: false,\n // A map of state changes to run before instantiation,\n // where the key is the path and value is the state value\n stateChanges: {},\n // Sequence execution returns promises\n returnSequencePromise: false,\n // Enables handling hotReloading. Hot reloading it detected and warned about. When active\n // Cerebral will do a smart merge of any changes hot reloaded and update the devtools\n hotReloading: false\n})\n```\n\n## Methods\n\n### getState\n\nReturns state from the state tree\n\n```js\nconst someState = app.getState('some.state')\n```\n\n### getSequence\n\nReturns sequence from Cerebral\n\n```js\nconst someSequence = app.getSequence('some.sequence')\n// Run sequence\nsomeSequence({ foo: 'bar' })\n```\n\n### getModel\n\nReturns the model (state tree) of Cerebral\n\n```js\nconst model = app.getModel()\n```\n\n### flush\n\nFlushes out changes to UI based on recent state changes, can be forced\n\n```js\napp.flush()\n```\n\n### runSequence\n\nAllows you to run an arbitrary function tree definition\n\n```js\napp.runSequence('someSequence', [actionA, actionB], { foo: 'bar' })\n```\n\n### addModule\n\nAllows you to add modules to the app after instantiation (lazy)\n\n```js\napp.addModule('someModule', module)\n```\n\n### removeModule\n\nAllows you to remove modules from the app\n\n```js\napp.removeModule('someModule')\n```\n\n## Events\n\n### initialized:model\n\nTriggers when Cerebral model has initialized.\n\n```js\napp.on('initialized:model', () => {})\n```\n\n### initialized\n\nTriggers when Cerebral app has initialized.\n\n```js\napp.on('initialized', () => {})\n```\n\n### moduleAdded\n\nTriggers when Cerebral adds a module is added.\n\n```js\napp.on('moduleAdded', (path, module) => {})\n```\n\n### moduleRemoved\n\nTriggers when Cerebral removes a module.\n\n```js\napp.on('moduleRemoved', (path, module) => {})\n```\n\n### flush\n\nTriggered whenever Cerebral flushes out changes to the UI. Passes a map of changes.\n\n```js\napp.on('flush', (changes) => {})\n```\n\n### start\n\nTriggered whenever Cerebral starts a sequence execution.\n\n```js\napp.on('start', (execution, payload) => {})\n```\n\n### end\n\nTriggered whenever Cerebral ends a sequence execution.\n\n```js\napp.on('end', (execution, payload) => {})\n```\n\n### pathStart\n\nTriggered whenever Cerebral starts execution a path in a sequence\n\n```js\napp.on('pathStart', (execution, payload) => {})\n```\n\n### pathEnd\n\nTriggered whenever Cerebral ends execution a path in a sequence\n\n```js\napp.on('pathEnd', (execution, payload) => {})\n```\n\n### functionStart\n\nTriggered whenever Cerebral starts executing an action.\n\n```js\napp.on('functionStart', (execution, functionDetails, payload) => {})\n```\n\n### functionEnd\n\nTriggered whenever Cerebral ends executing an action.\n\n```js\napp.on(\n 'functionEnd',\n (execution, functionDetails, payload, result) => {}\n)\n```\n\n### asyncFunction\n\nTriggered whenever Cerebral executed an async action.\n\n```js\napp.on('asyncFunction', (execution, functionDetails, payload) => {})\n```\n\n### parallelStart\n\nTriggered whenever Cerebral executes actions in parallel.\n\n```js\napp.on(\n 'parallelStart',\n (execution, payload, functionsToResolveCount) => {}\n)\n```\n\n### parallelProgress\n\nTriggered whenever Cerebral executes actions in parallel.\n\n```js\napp.on(\n 'parallelProgress',\n (execution, payload, functionsStillResolvingCount) => {}\n)\n```\n\n### parallelEnd\n\nTriggered whenever Cerebral ends executing actions in parallel.\n\n```js\napp.on('parallelEnd', (execution, payload, functionsExecutedCount) => {})\n```\n\n### remember\n\nTriggered whenever Cerebral travels back in time. Passes the timestamp it travelled to.\n\n```js\napp.on('remember', (datetime) => {})\n```\n\n### mutation\n\nTriggered whenever Cerebral mutated the state\n\n```js\napp.on('mutation', (mutation) => {})\n```\n","title":"App"},"computed":{"raw":"# Compute\n\nComputeds calculate and cache derived state values. Using computeds helps to keep logic out of the application view components and improves performance.\n\n```js\nimport { state } from 'cerebral'\n\nexport const title = (get) => {\n return `Hi ${get(state`user.name`)}`\n}\n```\n\nYou use the **get** function to retrieve state and other computed values from the state tree. It will automatically track the computed to optimally figure out when it needs to recalculate.\n\nYou attach these computeds directly to your state:\n\n```js\nimport { title } from './computed'\n\nexport default {\n state: {\n user: {\n name: 'Bob'\n },\n title\n }\n}\n```\n\nTo use a computed just point to it as if it was normal state, here shown with React:\n\n```js\nimport React from 'react'\nimport { state } from 'cerebral'\nimport { connect } from '@cerebral/react'\n\nexport default connect(\n {\n hello: state`title`\n },\n function App({ hello }) {\n return (\n <h1>{title}</h1>\n )\n }\n)\n```","title":"Compute"},"devtools":{"raw":"# Devtools\n\nYou can pass some options to the devtools to balance the processing and memory footprint:\n\n```js\nimport App from 'cerebral'\nimport Devtools from 'cerebral/devtools'\nimport main from './main'\n\nlet devtools = null\n\nif (process.env.NODE_ENV !== 'production') {\n devtools = Devtools({\n // Connect to Electron debugger (external debugger). It will\n // fall back to chrome extension if unable to connect\n host: 'localhost:8585',\n\n // By default devtools connects to \"ws://\". This option should be set to true\n // when browser operates on https. Follow debugger instructions for\n // further configuration\n https: false,\n\n // By default the devtools tries to reconnect\n // to debugger when it can not be reached, but\n // you can turn it off\n reconnect: true,\n\n // Time travel\n storeMutations: true,\n\n // Shows a warning when you have components with number of\n // state dependencies or signals above the set number\n bigComponentsWarning: 5,\n\n // Warnings when passing objects and arrays as props to child\n // components. They should rather be connected directly\n warnStateProps: true,\n\n // In addition to these basic JavaScript types: Object, Array, String, Number\n // and Boolean, types of File, FileList, Blob, ImageData and RegExp is allowed to be stored in state\n // tree. You can add additional types if you know what you are doing :)\n allowedTypes: [Blob]\n })\n}\n\nconst app = App(main, {\n devtools\n})\n```","title":"Devtools"},"error":{"raw":"# Error\n\nThe **CerebralError** allows you to create your own error types to be used to catch errors in your sequences. The **catch** handler defined on the module will propagate up to parent modules. That means if a nested module does not catch an error, one of the parent modules can catch it if configured to do so.\n\n```js\nimport { CerebralError } from 'cerebral'\n\nexport class MyError extends CerebralError {}\n```\n\nThe error is thrown like this:\n\n```js\nimport { MyError } from './errors'\n\nfunction someAction() {\n throw new MyError('Some message', {\n // any details\n })\n}\n```\n\nAnd caught like this:\n\n```js\nimport { MyError } from './errors'\nimport * as sequences from './sequences'\n\nexport default {\n sequences,\n catch: [\n [MyError, sequences.handleError]\n ]\n}\n```\n","title":"Error"},"factories":{"raw":"# Factories\n\nYou can call factories to create actions for you. These actions will help you change state and control the flow of execution.\n\nRead more about factories in the [the guide](/docs/guides/factories) article.\n\n## Store factories\n\nThe methods for changing state within actions are also available as factories.\n\nAll store are imported as members of the 'cerebral/factories' module. For example:\n\n```js\nimport { set } from 'cerebral/factories'\n```\n\n### concat\n\nConcatenate a value to an array\n\n```js\nconcat(state`some.list`, ['foo', 'bar'])\n```\n\n### increment\n\nIncrement an integer value by another integer value into an array. The default increment is 1, and a negative value effectively does a decrement.\n\n```js\nincrement(state`some.integer`)\nincrement(state`some.integer`, -5)\nincrement(state`some.integer`, state`some.otherInteger`)\nincrement(state`some.integer`, props`some.otherInteger`)\n```\n\n### merge\n\nMerge objects into existing value. If no value exists, an empty object will be created. Merge supports using operator tags on key values:\n\n```js\nmerge(state`clients.$draft`, props`newDraft`, {\n foo: 'bar',\n bar: props`baz`\n})\n```\n\n### pop\n\nPop a value off an array (removes last element from array).\n\n```js\npop(state`some.list`)\n```\n\n### push\n\nPush value into an array (adds the element at the end of the array).\n\n```js\npush(state`some.list`, 'foo')\n```\n\n### set\n\nSet a target value in the state or props.\n\n```js\nset(state`foo.bar`, true)\nset(props`foo`, true)\n```\n\nOptionally transform the value before setting\n\n```js\nset(state`some.number`, props`number`, (value) => value * 2)\n```\n\n### shift\n\nShift a value off an array (removes first element in array).\n\n```js\nshift(state`some.list`),\n```\n\n### splice\n\nSplice an array in place.\n\n```js\nsplice(state`some.list`, 0, 2)\n```\n\n### toggle\n\nToggle a boolean value.\n\n```js\ntoggle(state`user.$toolbar`)\n```\n\n### unset\n\nUnset key from object.\n\n```js\nunset(state`clients.all.${props`key`}`)\n```\n\n### unshift\n\nUnshift a value into an array (adds the element at the start of the array).\n\n```js\nunshift(state`some.list`, 'foo')\n```\n\n## Flow control factories\n\nThese factories help control the execution flow.\n\n### debounce\n\nHold action until the given amount of time in milliseconds has passed. If the\nsequence triggers again within this time frame, the previous sequence goes down the\n\"discard\" path while the new sequence holds for the given time. This is\ntypically used for typeahead functionality. For a debounce that is shared\nacross different signals, you can use `debounce.shared()` (see example below).\n\nPlease note that the `discard` path has to be present even if it is most often\nempty.\n\n```js\nimport { debounce } from 'cerebral/factories'\n\nexport default [\n debounce(200),\n {\n continue: runThisActionOrSequence,\n discard: []\n }\n]\n```\n\n`debounce.shared()` is typically used with factories, for example to show\nnotifications where a previous notification should be cancelled by a new one.\n\n```js\nimport { debounce, set, unset } from 'cerebral/factories'\nimport { state } from 'cerebral'\n\nconst sharedDebounce = debounce.shared()\nfunction showNotificationFactory(message, ms) {\n return [\n set(state.notification, message),\n sharedDebounce(ms),\n {\n continue: unset(state.notification),\n discard: []\n }\n ]\n}\n```\n\nNow when this notification factory is used in different sequence, the call to\n`debounceShared` will share the same debounce execution state:\n\n```js\nimport * as factories from './factories'\n\nexport default factories.showNotification('User logged in', 5000)\n```\n\n### equals\n\nThis operator chooses a specific path based on the provided value.\n\n```js\nimport { equals } from 'cerebral/factories'\nimport { state } from 'cerebral'\n\nexport default [\n equals(state`user.role`), {\n admin: [],\n user: [],\n otherwise: [] // When no match\n }\n],\n```\n\n### wait\n\nWait for the given time in milliseconds and then continue chain.\n\n```js\nimport { wait } from 'cerebral/factories'\n\nexport default [\n wait(200),\n doSomethingAfterWaiting\n]\n```\n\nIf you need to wait while executing in parallel, you should use a `continue`\npath to isolate the sequence to be run:\n\n```js\nimport { wait } from 'cerebral/factories'\nimport { parallel } from 'cerebral'\n\nexport default\n someAction,\n parallel('my parallel with wait', [\n wait(200), {\n continue: [doSomethingAfterWaiting]\n },\n otherActionInParallel\n ])\n]\n```\n\n### when\n\nRun signal path depending on a truth value or function evaluation.\n\n```js\nimport { when } from 'cerebral/factories'\nimport { state } from 'cerebral'\n\nexport default [\n when(state`foo.isAwesome`),\n {\n true: [],\n false: []\n },\n // You can also pass your own function\n when(state`foo.isAwesome`, (value) => value.length === 3),\n {\n true: [],\n false: []\n }\n]\n```\n\nWhen used with a truth function, the `when` operator supports more then a single\n\"value\" argument. The predicate function must come last.\n\n```js\nimport { when } from 'cerebral/factories'\nimport { props, state } from 'cerebral'\n\nexport default [\n when(\n state`clients.$draft.key`,\n props`key`,\n (draftKey, updatedKey) => draftKey === updatedKey\n ),\n {\n true: set(state`clients.$draft`, props`value`),\n false: []\n }\n]\n```\n","title":"Factories"},"module":{"raw":"# Module\n\nThe module is how you structure your application, it holds:\n\n```js\n{\n state,\n sequences,\n reactions,\n providers,\n catch,\n modules,\n}\n```\n\nYou instantiate your application with a root module:\n\n```js\nconst app = App({\n state: {}\n})\n```\n\nAnd you extend this root module with nested modules:\n\n```js\nconst app = App({\n state: {},\n modules: {\n moduleA,\n moduleB\n }\n})\n```\n","title":"Module"},"providers":{"raw":"# Providers\n\nA provider exposes functionality to your actions. Typically to run side effects. Each action has a unique context object where the providers are populated.\n\nThis provider is automatically wrapped by the debugger, where available.\n\n```js\nexport const greetProvider = {\n greet() {\n return 'hello'\n }\n}\n```\n\n```js\nimport * as providers from './providers'\n\nexport default {\n state: {},\n providers\n}\n```\n\nYou also have access to the context inside your provider. This will allow you to leverage existing providers. The context is exposed as `this.context`. This keeps the API concise and under the hood we can do prototypal optimizations.\n\n```js\nexport default {\n triggerSignalOnNativeEvent(event, sequence) {\n window.addEventListener(event, () => {\n this.context.get(sequence)()\n })\n }\n}\n```\n\n## Provider\n\nYou can optionally use the **Provider** factory. It allows you to pass some options related to debugging:\n\n```js\nimport { Provider } from 'cerebral'\n\nexport const myProvider = Provider({}, {\n wrap: false\n})\n```\n\nThis provider will not be tracked by debugger. Optionally you can intercept how the provider should work when wrapped by the devtools:\n\n```js\nimport { Provider } from 'cerebral'\n\nexport const myProvider = Provider({}, {\n wrap(context) {\n return {}\n }\n})\n```\n\nA provider can also by defined as a function which receives the current context. This prevents some optimizations, but might be necessary:\n```js\nexport const greetProvider = (context) => {\n return {}\n}\n```","title":"Providers"},"proxy":{"raw":"# Proxy\n\nThe proxies exposed by Cerebral allows you to target state, sequences and props. They require the [babel-plugin-cerebral](https://www.npmjs.com/package/babel-plugin-cerebral) which transforms the proxies into [template literal tags](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals).\n\n\n## State\n\n```js\nimport { state } from 'cerebral'\n\n// In action\nfunction myAction ({ store }) {\n store.set(state.foo, 'bar')\n}\n\n// In factories\n[\n set(state.foo, 'bar'),\n when(state.isAwesome)\n]\n\n// In computed\nCompute({\n foo: state.foo\n}, () => {})\n\n// In reaction\nReaction({\n foo: state.foo\n}, () => {})\n\n// In connect\nconnect({\n foo: state.foo\n}, ...)\n```\n\n## Sequences\n\n```js\nimport { sequences } from 'cerebral'\n\n// In action\nfunction myAction ({ get }) {\n const mySequence = get(sequences.mySequence)\n}\n\n// In factories\n[\n onMessage('some_channel', sequences.onMessage)\n]\n\n// In reaction\nReaction({\n foo: state.foo\n}, ({ foo, get }) => {\n get(sequences.mySequence)({ foo })\n})\n\n// In connect\nconnect({\n foo: state.foo,\n onClick: sequences.doThis\n}, ...)\n```\n\n## Compute\n\n```js\nimport { computed } from 'cerebral'\n\n// In action\nfunction myAction ({ get }) {\n const someValue = get(computed.someValue)\n}\n\n// In factories\n[\n when(computed.appIsAwesome)\n]\n\n// In computed\nCompute({\n foo: computed.foo\n}, ({ foo }) => {})\n\n// In reaction\nReaction({\n foo: computed.foo\n}, ({ foo }) => {})\n\n// In connect\nconnect({\n foo: computed.foo\n}, ...)\n```\n\n## Props\n\n```js\nimport { props } from 'cerebral'\n\n// In factories\n[\n when(props.isCool)\n]\n\n// In computed\nCompute({\n foo: props.foo\n}, ({ foo }) => {})\n\n// In connect\nconnect({\n item: state.items[props.index]\n}, ...)\n```\n\n## ModuleState\n\n```js\nimport { moduleState } from 'cerebral'\n\n// In action\nfunction myAction ({ store }) {\n store.set(moduleState.foo, 'bar')\n}\n\n// In factories\n[\n set(moduleState.foo, 'bar'),\n when(moduleState.isAwesome)\n]\n\n// In computed\nCompute({\n foo: moduleState.foo\n}, () => {})\n\n// In reaction\nReaction({\n foo: moduleState.foo\n}, () => {})\n```\n\n## ModuleSequences\n\n```js\nimport { moduleSequences } from 'cerebral'\n\n// In action\nfunction myAction ({ get }) {\n const mySequence = get(moduleSequences.mySequence)\n}\n\n// In factories\n[\n onMessage('some_channel', moduleSequences.onMessage)\n]\n\n// In reaction\nReaction({\n foo: state.foo\n}, ({ foo, get }) => {\n get(moduleSequences.mySequence)({ foo })\n})\n```\n\n## String\n\nThe string can not e converted to a proxy cause it represents a string, but you can combine it with proxies:\n\n```js\nimport { state, string } from 'cerebral'\n\n// In factories\n[\n httpGet(string`/items/${state.currentItemId}`)\n]\n```","title":"Proxy"},"reaction":{"raw":"# Reaction\n\nYou will typically use reactions with your components, for example:\n\n```js\nimport * as React from 'react'\nimport { connect } from '@cerebral/react'\nimport { state, sequences } from 'cerebral'\n\nexport default connect(\n {\n inputValue: state`inputValue`,\n changeInputValue: sequences`changeInputValue`\n },\n class MyComponent extends React.Component {\n componentDidMount() {\n this.props.reaction(\n 'focusUsername',\n {\n error: state`usernameError`\n },\n ({ error }) => error && this.input.focus()\n )\n }\n render() {\n return (\n <input\n ref={(node) => {\n this.input = node\n }}\n value={this.props.inputValue}\n onChange={(event) =>\n this.props.changeInputValue({ value: event.target.value })\n }\n />\n )\n }\n }\n)\n```","title":"Reaction"},"sequence":{"raw":"# Sequence\n\nSequences can be expressed with a simple array:\n\n```js\nexport const mySequence = []\n```\n\nYou populate these arrays with actions:\n\n```js\nexport const mySequence = [actions.someAction]\n```\n\nYou attach sequences to modules:\n\n```js\nimport * as sequences from './sequences'\n\nexport default {\n sequences\n}\n```\n\n## Async\n\nBy default sequences run completely synchronous, but an action might run asynchronously thus making the sequence async. When an action returns a promise it means it runs async.\n\n```js\nexport function myAction() {\n return Promise.resolve()\n}\n```\n\nYou could also use an **async** function:\n\n```js\nexport async function myAction() {\n return { foo: 'bar' }\n}\n```\n\n## Sequence factory\n\nSimple format of a sequence is to use an array literal, as explained above. Actions are run one after the other. If the action returns a promise Cerebral will wait until it resolves before moving to the next action:\n\n```js\nimport * as actions from '../actions'\n\nexport const mySequence = [actions.someAction]\n```\n\nThe array is converted to a sequence, but you can also be explicit about it:\n\n```js\nimport { sequence } from 'cerebral/factories'\nimport * as actions from './actions'\n\nexport const mySequence = sequence([\n actions.someAction\n])\n```\n\nYou can name a sequence, which will be displayed in debugger:\n\n```js\nimport { sequence } from 'cerebral/factories'\nimport * as actions from './actions'\n\nexport const mySequence = sequence('my sequence', [\n actions.someAction\n])\n```\n\nYou can compose a sequence into an existing sequence. The debugger will show this composition:\n\n```js\nimport * as actions from '../actions'\n\nexport const myOtherSequence = [actions.doThis]\n\nexport const mySequence = [actions.someAction, myOtherSequence]\n```\n\n## Parallel\n\nCerebral can not truly run actions in parallel (JavaScript is single threaded), but it can trigger multiple asynchronous actions at the same time, just like **Promise.all**. That means when Cerebral triggers actions defined within a parallel, it will not wait if a promise is returned, it will just move on to the next action. When all actions within a parallel is resolved it will move to the action after the parallel definition, if any:\n\n```js\nimport { parallel } from 'cerebral/factories'\nimport * as actions from './actions'\n\nexport const mySequence = parallel([\n actions.someAsyncAction,\n actions.someOtherAsyncAction\n])\n```\n\nYou can name a parallel, which will be displayed in debugger:\n\n```js\nimport { parallel } from 'cerebral/factories'\nimport * as actions from './actions'\n\nexport const mySequence = parallel('my parallel', [\n actions.someAsyncAction,\n actions.someOtherAsyncAction\n])\n```\n\nYou can compose parallel into any existing sequence:\n\n```js\nimport { parallel } from 'cerebral/factories'\nimport * as actions from './actions'\n\nexport const mySequence = [\n actions.someAction,\n parallel('my parallel', [\n actions.someAsyncAction,\n actions.someOtherAsyncAction\n ])\n]\n```\n\nNote that you can also compose sequences into *parallel*. That means when both sequences are done running it will move on.\n\n## Paths\n\nYou can diverge execution by defining paths in your sequences.\n\n```js\nimport * as actions from './actions'\n\nexport const mySequence = [\n actions.getItems,\n {\n success: [],\n error: []\n }\n]\n```\n\nThe action returned by **getItems** will now have access to a success and an error path and can call those based on the result of the http request.\n\nYou can define any path to execute:\n\n```js\nimport * as actions from './actions'\n\nexport const mySequence = [\n actions.myAction,\n {\n foo: [],\n bar: [],\n bananas: [],\n apples: []\n }\n]\n```\n\nWhen these paths are defined you will have access to corresponding paths in the action preceding the paths:\n\n```js\nfunction myAction({ path }) {\n path.foo\n path.bar\n path.bananas\n path.apples\n}\n```\n\nTo actually diverge down the path you have to call it and return it from the action:\n\n```js\nfunction myAction({ path }) {\n return path.foo()\n}\n```\n\nOptionally pass a payload:\n\n```js\nfunction myAction({ path }) {\n return path.bananas({ foo: 'bar' })\n}\n```\n\nWith promises you just return it the same way:\n\n```js\nfunction myAction({ someProvider, path }) {\n return someProvider\n .doAsync()\n .then((result) => path.bananas({ data: result.data }))\n}\n```\n","title":"Sequence"},"state":{"raw":"# State\n\n## Get state\n\nThe only way to get state in your application is by connecting it to a component or grabbing it in an action.\n\n```js\nimport { state, moduleState } from 'cerebral'\n\nfunction someAction({ get }) {\n const stateAtSomePath = get(state`some.path`)\n // Get from module running this execution\n const stateAtModulePath = get(moduleState`isLoading`)\n}\n```\n\n## Updating state\n\nThe only way to update the state of your application is in an action. Here is a list of all possible state mutations you can do:\n\n```js\nfunction someAction({ store }) {\n // Concats passed array to existing array\n store.concat('some.path', ['someValueA', 'someValueB'])\n // Increment value at given path (default increment is 1)\n store.increment('some.path', 1)\n // Merge the keys and their values into existing object. Handled as a\n // change on all paths merged in\n store.merge('some.path', {\n some: 'value'\n })\n // Removes last item in array\n store.pop('some.path')\n // Pushes a value to the end of the array\n store.push('some.path', 'someValue')\n // Set or replace a value\n store.set('some.path', 'someValue')\n // Removes first item in array\n store.shift('some.path')\n // Splices arrays\n store.splice('some.path', 2, 1)\n // Toggle a boolean value\n store.toggle('some.path')\n // Unset a key and its value\n store.unset('some.path')\n // Puts the value at the beginning of the array\n store.unshift('some.path', 'someValue')\n\n // To change state of a module, use the moduleState tag\n store.set(moduleState`foo`, 'bar')\n}\n```\n\n**NOTE!** You should not extract state and change it directly in your actions or components. This will not be tracked by Cerebral. That means a render will not be triggered and the debugger will not know about it. Treat your state as if it was immutable and only change it using the **store API**.\n\n## Special values support\n\nWhen building an application you often need to keep things like files and blobs in your state for further processing. Cerebral supports these kinds of values because they will never change, or changing them can be used with existing store API. This is the list of supported types:\n\n* **File**\n* **FilesList**\n* **Blob**\n* **ImageData**\n* **RegExp**\n\nIf you want to force Cerebral to support other types as well, you can do that with a devtools option. This is perfectly okay, but remember all state changes has to be done through the store API.\n","title":"State"},"test":{"raw":"# Test\n\n## Snapshot testing\n\n### Introduction\n\n**1. Run the sequence**\n\nOpen up your app and run the sequence you want to test.\n\n**2. Create test in debugger**\n\nIn the debugger there is a button in the sequence list called \"Create sequence test\". Select the sequence you just triggered and click this button. The test is copied to the clipboard.\n\n**3. Run test**\n\nIt is recommended to use [JEST](https://facebook.github.io/jest/). Just paste what you have in your clipboard and it will look something like this.\n\n```js\ntest('should filter on all', () => {\n return Snapshot(main) // main is the main module\n .run('filterClicked', { filter: 'all' })\n .then((snapshot) => {\n expect(snapshot.get()).toMatchSnapshot()\n })\n})\n```\n\nRun the test to create the first snapshot. Any changes to your app that affects this sequence will be yelled at you by Jest.\n\n### Snapshot\n\nCreates the test and returns a promise. Pass it the main module of your application.\n\n```js\nSnapshot(main)\n```\n\n### run\n\nRuns a sequence with an optional payload. It returns a promise, passing the snapshot.\n\n```js\nSnapshot(main)\n .run('some.sequence', { foo: 'bar' })\n .then((snapshot) => {})\n```\n\n### mutate\n\nRuns a mutation in the state store before the sequence runs.\n\n```js\nSnapshot(main).mutate('set', 'some.state.path', 'someValue')\n```\n\n### mock\n\nMocks out a provider that will be called in the sequence. Can give an optional return value. If provider is called multiple times, you will need multiple calls to mock.\n\n```js\nSnapshot(main).mock('someProvider.someMethod', 'someReturnedValue')\n```\n\nThe mock can also be a function with `(context, ...args)` signature where args are the arguments passed in the\ncall to the provider method.\n\n```js\nSnapshot(main).mock('someProvider.someMethod', (context, ..args) => {\n // mock operation here\n})\n```\n\n### mockResolvedPromise\n\nMocks out a provider with a returned promise that resolves with an optional value.\n\n```js\nSnapshot(main).mockResolvedPromise(\n 'someProvider.someMethod',\n 'someReturnedValue'\n)\n```\n\n### mockRejectedPromise\n\nMocks out a provider with a returned promise that rejects with an optional value.\n\n```js\nSnapshot(main).mockRejectedPromise(\n 'someProvider.someMethod',\n 'someReturnedValue'\n)\n```\n\n## Assertion\n\n### Components\n\nThe **Container** you use to expose Cerebral to your components can also be used when testing. This is beneficial if you want to test a section of your UI interacts correctly with the Cerebral app.\n\n```js\nimport React from 'react'\nimport { mount } from 'enzyme'\nimport assert from 'assert'\nimport { Container } from '@cerebral/react'\nimport App from 'cerebral'\n\nimport Button from './Button'\n\ndescribe('<Button />', () => {\n it('should pass foo state on click', () => {\n const testModule = () => ({\n state: {\n foo: 'bar'\n },\n sequences: {\n clicked: ({ props }) => assert.equal(props.foo, 'bar')\n }\n })\n const app = App(testModule)\n const wrapper = mount(\n <Container app={app}>\n <Button />\n </Container>\n )\n expect(wrapper.find('.foo')).to.have.length(1)\n })\n})\n```\n\n### Compute\n\nThe `runCompute` test helper accepts the `computed` and `fixture` arguments and returns the computed output.\n\n```js\nimport { props, state } from 'cerebral'\nimport { runCompute } from 'cerebral/test'\n\nimport multiply from './multiply'\n\nit('should multiply by the specified number', () => {\n const result = runCompute(multiply, {\n state: { number: 5 },\n props: { multiplyBy: 2 }\n })\n\n assert.equal(result, 10)\n})\n```\n\n### Actions\n\nThe `runAction` test helper accepts the `action` and `fixture` arguments and returns a promise.\n\n```js\nimport { state } from 'cerebral'\nimport { runAction } from 'cerebral/test'\n\nimport increment from './increment'\n\nit('should increment numbers in state', () => {\n return runAction(increment, { state: { number: 1 } }).then(({ state }) =>\n assert.equal(state.number, 2)\n )\n})\n```\n\nThe `result` object passed when the promise resolves contains `state`, `props` and `output` properties.\n\n```js\n{\n state,\n props: {\n // props data received by action\n },\n output: {\n // action output data\n }\n}\n```\n\n### Sequences\n\nThe `runSequence` test helper accepts a `sequence` and `fixture` arguments and returns a promise.\n\n```js\nimport { state } from 'cerebral'\nimport { runSequence } from 'cerebral/test'\n\nimport increment from './increment'\n\nit('should increment numbers in state', () => {\n return runSequence([increment], { state: { number: 1 } }).then(({ state }) =>\n assert.equal(state.number, 2)\n )\n})\n```\n\nThe `result` object passed when the promise resolves contains `state`, `props` and `output` properties.\n\n```js\n{\n state,\n props: {\n // props data received by sequence\n },\n output: {\n // sequence output data\n }\n}\n```\n\n### CerebralTest\n\nThe `CerebralTest` factory returns `runSequence`, `setState` and `getState` functions. This allows you to run multiple sequences in the context of the same controller instance.\n\n```js\nimport { CerebralTest } from 'cerebral/test'\nimport math from './math'\n\nit('should accumulate a count', () => {\n const test = CerebralTest(math) // Expects a Module\n\n test.setState('count', 0)\n\n return test.runSequence('plusOne').then(({ state }) => {\n assert.equal(state.count, 1)\n\n return test.runSequence('plus', { value: 2 }).then(() => {\n assert.equal(test.getState('count'), 3)\n })\n })\n})\n```\n\nNote that state initialized in a module takes precedence over the state property of a fixture. Example:\n\n```js\nconst fixture = {\n // Override default state in modules\n state: {\n app: {\n showNavigation: true\n }\n },\n modules: {\n app\n }\n}\n```\n\n#### Options\n\nThe optional `options` argument contain the the following options:\n\n`recordActions: true|false|'byName'`\n\n```js\nimport { CerebralTest } from 'cerebral/test'\nimport math from './math'\n\nit('should accumulate a count', () => {\n const test = CerebralTest(math, {\n recordActions: 'byName'\n })\n\n test.setState('count', 0)\n\n return test\n .runSequence('plusOne', {\n incrementBy: 1\n })\n .then(({ increment }) => {\n assert.equal(increment.props.incrementBy, 1)\n })\n})\n```\n\nWhen `recordActions: true` is specified each action will record its props/output against its index within the sequence. When `recordActions: 'byName'` is specified each action will record its output against an named property in the result.\n\nThe `result` object passed when the promise resolves contains `state` and an object for each named action in the sequence with the same name as the actions with `props` and `output` properties.\n","title":"Test"},"universalapp":{"raw":"# Universal App\n\nThe Universal App allows you to put your application in its initial state on the server. In combination with your chosen view layer you can now render the application on the server and show it near instantly in the context of the current user. When the client side application loads it will piggyback on the existing DOM and effectively rehydrate the minimal state from the server to make it up to date, meaning that the pure HTML responded from your server and the loading of the actual application is transparent.\n\nRead more about server side rendering in the [SSR guide](/docs/guides/ssr).\n\n**Note** that when using JSX syntax it is wise to also transpile your server side code, which this example shows.\n\n```js\nimport { UniversalApp } from 'cerebral'\nimport main from './main'\n\nconst app = UniversalApp(main)\n```\n\n## Methods\n\n### runSequence\n\nIf you need to update the state of the controller you can run a sequence execution for doing so:\n\n```js\nimport { UniversalApp, state } from 'cerebral'\nimport main from './main'\n\nconst app = UniversalApp(main)\n\napp\n .runSequence(\n [\n function myAction({ store, props }) {\n store.set(state.isAwesome, props.isAwesome)\n }\n ],\n {\n isAwesome: true\n }\n )\n .then(() => {\n // I am done running\n })\n```\n\nYou can run a predefined sequence, which is defined inside a module as well:\n\n```js\nimport { UniversalApp } from 'cerebral'\nimport main from './main'\n\nconst app = UniversalApp(main)\n\napp.runSequence('some.module.aSequence', { isAwesome: true }).then(() => {\n // I am done running\n})\n```\n\n**NOTE!** You should instantiate the app for each run you want to do.\n\n### setState\n\nFinally, you can (synchronously) set a value inside the state directly, using a path:\n\n```js\nimport { UniversalApp } from 'cerebral'\nimport main from './main'\n\nconst app = UniversalApp(main)\n\napp.setState('app.foo', 123)\n```\n\n### getChanges\n\nReturns a map of the changes made.\n\n```js\nimport { UniversalApp } from 'cerebral'\nimport main from './main'\n\nconst app = UniversalApp(main)\n\napp.runSequence('app.aSequence', { isAwesome: true }).then(() => {\n app.getChanges() // {\"app.isAwesome\": true}\n})\n```\n\n### getScript\n\nWhen the client side application loads it will do its first render with the default state, meaning that if the server updated the state this is now out of sync. Using the **getScript** method you will get a script tag you can inject into the _HEAD_ of the returned HTML. Cerebral will use this to bring your client side application state up to date with the server.\n\n```js\nimport { UniversalApp, state } from 'cerebral'\nimport main from './main'\nimport fs from 'fs'\n\n/*\n <!DOCTYPE html>\n <html>\n <head>\n {{CEREBRAL_SCRIPT}}\n </head>\n <body>\n <div id=\"app\">{{APP}}</div>\n </body>\n </html>\n*/\nconst indexTemplate = fs.readFileSync('index.template.html').toString()\n\nconst app = UniversalApp(main)\n\napp\n .run(\n [\n function myAction({ store, props }) {\n store.set(state.app.isAwesome, props.isAwesome)\n }\n ],\n {\n isAwesome: true\n }\n )\n .then(() => {\n const index = indexTemplate.replace(\n '{{CEREBRAL_SCRIPT}}',\n app.getScript()\n )\n })\n```\n\n## Render\n\nDepending on the view layer of your choice you can bring all of this together:\n\n```js\nimport React from 'react'\nimport express from 'express'\nimport fs from 'fs'\nimport { renderToString } from 'react-dom/server'\nimport { UniversalApp } from 'cerebral'\nimport { Container } from 'cerebral/react'\nimport main from '../client/main'\nimport AppComponent from '../client/components/App'\nimport loadAppSequence from './loadAppSequence'\n\nconst server = express()\nconst indexTemplate = fs.readFileSync('index.template.html').toString()\n\nserver.get('/', (req, res) => {\n const app = UniversalApp(main)\n\n app\n .run(loadAppSequence, {\n query: req.query,\n useragent: req.headers['user-agent']\n })\n .then(() => {\n const index = indexTemplate\n .replace('{{CEREBRAL_SCRIPT}}', app.getScript())\n .replace(\n '{{APP}}',\n renderToString(\n <Container app={app}>\n <App />\n </Container>\n )\n )\n\n res.send(index)\n })\n})\n\nserver.listen(3000)\n```\n\n## Transpile server code\n\nYou should run and build your Node instance with `babel`. Take a look at how you can run Node with babel [over here](https://babeljs.io/docs/usage/cli/#babel-node).\n","title":"Universal App"}},"migration":{"index":{"raw":"# 4.0\n\nThese are the constructs that Cerebral consists of:\n\n```js\nimport { Controller, Module, Provider, Compute, CerebralError } from 'cerebral'\n```\n\n## Module\n\nThe module is how you structure your application.\n\n```js\nconst app = Module({\n state: {},\n signals: {},\n providers: {},\n modules: {},\n catch: []\n})\n\n// Or callback\nconst app = Module(({ name, path, controller }) => ({\n state: {}\n}))\n```\n\n1. Providers are now an object instead of an array. This makes more sense as providers needs a name and we do not need this `provide` factory:\n\n```js\nconst app = Module({\n state: {},\n providers: {\n http: HttpProvider({})\n }\n})\n```\n\n2. The only way to `catch` an error now is at the module level. Errors propagate up to parent modules if not caught. Meaning there is no signal specific error catching or \"global\". \"Global\" would be your root level module.\n\n```js\nconst app = Module({\n state: {},\n catch: [[HttpProviderError, sequences.catchHttpError]]\n})\n```\n\n[Documentation](/docs/api/module)\n\n## Controller\n\nThe controller takes a module as first argument, and other options as a second argument.\n\n```js\nconst controller = Controller(rootModule, {\n devtools: null\n})\n```\n\nThe same goes for server side controller.\n\n[Documentation](/docs/api/controller)\n\n## Provider\n\nProviders will now have a stronger concept. The concept is being the API between your application and your tools of choice. It can only be defined in one way, an object with methods. This makes things consistent and also enforces the idea that you think of a provider as a \"bridge\" between your app and the tools your are using.\n\n```js\nconst myProvider = Provider({\n foo() {}\n})\n```\n\nYou can point to the existing context using `this.context`. It works this way to simplify with just one API surface and we can do prototypal optimizations under the hood.\n\n```js\nconst api = Provider({\n getUser() {\n return this.context.http.get('/user')\n }\n})\n```\n\nAll providers defined this way is automatically optimized and wrapped for debugger purposes. If you just want to use a 3rd party tool directly, you can still do that by just attaching it:\n\n```js\nModule({\n providers: { uuid }\n})\n```\n\n[Documentation](/docs/api/providers)\n\n## Compute\n\nThis is just a change to be consistent with the other APIs:\n\n```js\nconst myComputed = Compute(state`foo`, (foo) => ())\n```\n\n[Documentation](/docs/api/compute)\n\n## CerebralError\n\nTo more easily create different error types you can now define your errors by extending the CerebralError:\n\n```js\nimport { CerebralError } from 'cerebral'\n\nexport class AppError extends CerebralError {}\nexport class ApiError extends CerebralError {}\n```\n\n[Documentation](/docs/api/error)\n\n## Module state changes\n\nYou can point to the module to make state changes on module executing the signal:\n\n```js\nfunction myAction({ module }) {\n module.set('foo', 'bar')\n}\n```\n\nYou can now use a `module` tag to point to the state of the module running the signal:\n\n```js\n;[set(module`foo`, 'bar')]\n```\n\n[Documentation tags](/docs/api/tags)\n[Documentation state](/docs/api/state)\n\n## Testing\n\nThe `CerebralTest` API now takes a Module as first argument.\n\n```js\nimport { CerebralTest } from 'cerebral/test'\nimport app from './src/app' // A Module\n\nCerebralTest(app)\n```\n\n## Routing\n\nSince you now use a root `Module`, the router will need to be added there.\n\n```js\nimport { Controller, Module } from 'cerebral'\nimport router from './router' // Instance of the router module\n\nconst rootModule = Module({\n modules: {\n router\n }\n})\n\nconst controller = Controller(rootModule)\n```\n\n## Migration\n\n1. Change controller configuration to take in a top level module\n2. Wrap all modules in Module constructor\n3. Change configuration of providers to use object\n4. Change any custom providers to use the Provider factory\n5. Rename use of `compute` to `Compute`\n6. Any error catching now needs to be at module level without `new Map(...)`\n7. Recommended to extend any errors that can be caught from `CerebralError`, as you get serialization out of the box\n8. Change out any `CerebralTest` argument with a `Module`\n","title":"4.0"},"5_0":{"raw":"# 5.0\n\nThere are 4 focus points for this release:\n\n- Simplicity\n- Consistency\n- Approachability\n- Scope reduction\n\nWatch this video to get an introduction of the new release:\n\n```marksy\n<Youtube url=\"https://www.youtube.com/embed/5TaFHDir82w\" />\n```\n\nOne of the **big highlights** here is that all the addons are now removed. The reason is two part. One being a maintenance burden, but also that providers can very easily be built exactly how you want them to work. An example being the router, which [this guide shows you how to set up](/docs/guides/routing.html).\n\nPlease use the following demos for reference on how to write the new Cerebral code:\n\n- [TodoMVC using proxies](https://github.com/cerebral/cerebral/tree/next/packages/demos/todomvc)\n- [TodoMVC using traditional tags](https://github.com/cerebral/cerebral/tree/next/packages/demos/todomvc-tags)\n- [TodoMVC using Typescript](https://github.com/cerebral/cerebral/tree/next/packages/demos/todomvc-ts)\n\nYour application should work \"out of the box\" with the new version with a couple of exceptions. Please look at the migration for what breaks your current app and what gives deprecation warnings:\n\n## Broken\n\n### 1. Compute\n\nThere is a new signature `Compute`, please [read more about it here](/docs/api/computed.html)\n\n### 2. StateContainer\n\n```js\n// REMOVED\nimport { StateContainer } from '@cerebral/_view_'\n\n// INSTEAD\nimport App from 'cerebral'\nimport { Container } from '@cerebral/_view_'\nimport main from 'path/to/main/module'\n\nconst app = App(main)\n\n<Container app={app}>\n\n</Container>\n```\n\n## Deprecations\n\n### 1. Rename Controller\n\n```js\n// DEPRECATED\nimport { Controller } from 'cerebral'\n\nconst controller = Controller(...)\n\n// NEW\nimport App from 'cerebral'\n\nconst app = App(...)\n```\n\n### 2. Rename Universal Controller\n\n```js\n// DEPRECATED\nimport { UniversalController } from 'cerebral'\n\nconst controller = UniversalController(...)\n\n// NEW\nimport { UniversalApp } from 'cerebral'\n\nconst app = UniversalApp(...)\n```\n\n### 3. Rename Container prop\n\nSame for the other views as well.\n\n```js\n// DEPRECATED\nimport { Container } from '@cerebral/react'\n\nrender(\n <Container controller={controller}>\n\n </Container>\n)\n\n// NEW\nimport { Container } from '@cerebral/react'\n\nrender(\n <Container app={app}>\n\n </Container>\n)\n```\n\n### 4. Remove Module factory\n\n```js\n// DEPRECATED\nimport { Module } from 'cerebral'\n\nexport default Module({})\n\nexport default Module(() => {})\n\n// NEW\nexport default {}\n\nexport default () => {}\n```\n\nIf you are using Typescript:\n\n```ts\nimport { ModuleDefinition } from 'cerebral'\n\nconst module: ModuleDefinition = {}\n\nexport default module\n```\n\n### 5. Rename tags\n\n```js\n// DEPRECATED\nimport { signal, signals, module } from 'cerebral/tags'\n\n// NEW\nimport { sequences, moduleState } from 'cerebral'\n```\n\nNote that **sequences** grabs a single sequence or module with sequences, so both the previous functionalities of **signal** and **signals**. \n\n### 6. From tags to proxies\n\n```js\n// DEPRECATED\nimport * as tags from 'cerebral/tags'\n\n// NEW\nimport {\n string,\n props,\n state,\n sequences,\n moduleState,\n moduleSequences\n} from 'cerebral'\n```\n\n[Read more about proxies here](/docs/api/proxy)\n\n### 7. From operators to factories\n\nWe changed the name of \"operators\" to \"factories\", as that is what they really are.\n\n```js\n// DEPRECATED\nimport { set, push, merge } from 'cerebral/operators'\n\n// NEW\nimport { set, push, merge } from 'cerebral/factories'\n```\n\n## Replace addons\n\nSo we are removing addons from the monorepo in the next major version. This will lift a huge maintenance burder off of Cerebral. Instead we will focus on helping you build your own providers and encourage sharing your providers from your own Github repos.\n\n### Forms\nForms can be treated as \"complex inputs\". That means instead of controlling the whole form from within the state store, you rather let the form handle itself and the state store can hook into it. [formsy-react](https://github.com/formsy/formsy-react) is one such solution, though there are many others.\n\n### Http\nYou can use any http library out there, just expose the methods your are using on a provider. Look at [this guide](/docs/guides/index.html).\n\n### Routing\nYou can choose component based routing, any routing the framework exposes or you can choose a \"Cerebral first\" routing solution as seen [in this guide](/docs/guides/routing.html).\n\n### Local storage\nLocal storage is very straight forward to expose through a provider, though you might want something more powerful to expose and that is when you have solutions like [local-storage](https://www.npmjs.com/package/local-storage).\n\n### Firebase\nFirebase was one of the more comprehensive addons and it was developed early on when Google took over Firebase. Their API has gotten a lot of love and it is easy to now expose methods from the Firebase API as a provider and manage it that way.\n","title":"5.0"}},"contribute":{"index":{"raw":"# Introduction\n\nOpen source would never work without contributions, but it is difficult to get a sense of where you can put in an effort to help out on a project. Where is help needed? How does the project work? How do I create a pull request? On this page you will hopefully get the information you need to contribute to the Cerebral project.\n\n## Contribute to documentation\n\nContributing with missing explanations and wrong documentation is the **most important** contribution you can make to any project.\n\n```marksy\n<Youtube url=\"https://www.youtube.com/embed/5UXmyClZkjU\" />\n```\n\n## Contribute to website\n\nNew documentation like guides is a really great way to contribute as it will help others with specific use cases.\n\n```marksy\n<Youtube url=\"https://www.youtube.com/embed/yhDTzXSOD7E\" />\n```\n\n## Contribute to codebase\n\nBug fixes, refactors, typescript typings and new features is also a really great way to contribute. Mostly because you get insight into the code and get more ownership.\n\n```marksy\n<Youtube url=\"https://www.youtube.com/embed/TYkylI7Aado\" />\n```\n","title":"Introduction"},"issues":{"raw":"# Issues\n\nThis is an overview of current issues that requires a **pull request**. They have been commented with a recommended approach.\n","title":"Issues"}},"resources":{"index":{"raw":"# Utilities\n\nThis is a growing list of packages that may help you in the development of your Cerebral Project\n\n## state-forms\n\nA computed form - originally @cerebral/forms\n\n### Description\n\nForms are one of the most complex state management challenges out there. Before Cerebral was created I spent a lot of time developing formsy-react, which is a library that tries to solve forms with internal state. With the release of Cerebral we got a chance to explore the space of solving forms complexity with external state instead. To this day I have a hard time recommending a solution and you should not see this lib as \"the official way of managing forms with Cerebral\". There is nothing wrong thinking of a form as a very complex input where you only pass data into Cerebral on the submit of the form.\n\n[GitHub](https://github.com/garth/state-forms) |\n[npm](https://www.npmjs.com/package/state-forms)\n\n## @cerebral/storage\n\n### Description\n\nThis module exposes local storage or session storage as a provider, where it by default parses and serializes to JSON.\n\n```marksy\n<Info>\nNote: this one is not in npm yet, so you need to add the github url in `package.json`\n</Info>\n```\n\n[GitHub](https://github.com/psypersky/cerebral-local-storage)","title":"Utilities"}}}