Comparing version 0.14.0 to 0.14.1
{ | ||
"name": "cerebral", | ||
"version": "0.14.0", | ||
"version": "0.14.1", | ||
"description": "A state controller with its own debugger", | ||
@@ -12,3 +12,3 @@ "main": "src/index.js", | ||
"devtest": "nodeunit-watcher", | ||
"test": "node test.js" | ||
"test": "nodeunit tests" | ||
}, | ||
@@ -15,0 +15,0 @@ "author": "Christian Alfoni", |
149
README.md
@@ -1,2 +0,2 @@ | ||
# Cerebral ![build status](https://travis-ci.org/christianalfoni/cerebral.svg?branch=master) | ||
# Cerebral [![Build Status](https://travis-ci.org/christianalfoni/cerebral.svg?branch=master)](https://travis-ci.org/christianalfoni/cerebral) | ||
A state controller with its own debugger | ||
@@ -15,4 +15,4 @@ | ||
- **[NEW]** [Watch this video on signals and actions](https://www.youtube.com/watch?v=zkeBjGdn7uM) | ||
- [Watch this video on Cerebral](https://www.youtube.com/watch?v=xCIv4-Q2dtA) | ||
- [Watch this video on signals and actions](https://www.youtube.com/watch?v=ylJG4vUx_Tc) | ||
- [Read this article on why you might need Cerebral](http://www.christianalfoni.com/articles/2015_08_02_Why-we-are-doing-MVC-and-FLUX-wrong) | ||
@@ -48,6 +48,7 @@ - [Check out a demo using the debugger](http://www.christianalfoni.com/todomvc) | ||
- [Types](#types) | ||
- [Custom Types](#custom-types) | ||
- [Groups](#groups) | ||
#### Naming | ||
The way you think of signals is that something happened in your application. Either in your VIEW layer, a router, maybe a websocket connection etc. So the name of a signal should define what happened: "appMounted", "inputChanged", "formSubmitted". The actions are named by there purpose, like "setInputValue", "postForm" etc. This will make it very easy for you to read and understand the flow of the application. All signal definitions first tells you "what happened in your app". Then each action describes its part of the flow that occurs when the signal triggers. | ||
The way you think of signals is that something happened in your application. Either in your VIEW layer, a router, maybe a websocket connection etc. So the name of a signal should define what happened: "appMounted", "inputChanged", "formSubmitted". The actions are named by their purpose, like "setInputValue", "postForm" etc. This will make it very easy for you to read and understand the flow of the application. All signal definitions first tells you "what happened in your app". Then each action describes its part of the flow that occurs when the signal triggers. | ||
@@ -57,7 +58,7 @@ #### Action | ||
```js | ||
function MyAction () { | ||
function myAction () { | ||
}; | ||
export default MyAction; | ||
export default myAction; | ||
``` | ||
@@ -67,6 +68,7 @@ | ||
```js | ||
function MyAction (args, state, output) { | ||
// Args contains all arguments passed to the signal itself | ||
// and any args passed from one action to the next | ||
args | ||
function MyAction (input, state, output) { | ||
// Input contains all inputs passed to the signal itself | ||
// and any outputs from the previous actions. Using packages | ||
// you can also add default input like AJAX libs etc. | ||
input // {} | ||
@@ -92,5 +94,5 @@ // State contains the methods for mutating the state of | ||
// The output argument is what you use to resolve arguments | ||
// and choose paths. By default you can use "success" or "error" | ||
// path | ||
// The output argument is what you use to resolve values for | ||
// the next actions and choose paths. By default you can use | ||
// "success" or "error" path | ||
output({foo: 'bar'}); | ||
@@ -104,15 +106,15 @@ output.success({foo: 'bar'}); | ||
#### Chain | ||
*actions/SetLoading.js* | ||
*actions/setLoading.js* | ||
```js | ||
function SetLoading (args, state) { | ||
function setLoading (input, state) { | ||
state.set('isLoading', true); | ||
}; | ||
export default SetLoading; | ||
export default setLoading; | ||
``` | ||
*actions/SetTitle.js* | ||
*actions/setTitle.js* | ||
```js | ||
function SetLoading (args, state) { | ||
function setTitle (input, state) { | ||
state.set('title', 'Welcome!'); | ||
}; | ||
export default SetTitle; | ||
export default setTitle; | ||
``` | ||
@@ -123,8 +125,8 @@ *main.js* | ||
import SetLoading from './actions/SetLoading.js'; | ||
import SetTitle from './actions/SetTitle.js'; | ||
import setLoading from './actions/setLoading.js'; | ||
import setTitle from './actions/setTitle.js'; | ||
controller.signal('appMounted', | ||
SetLoading, | ||
SetTitle | ||
setLoading, | ||
setTitle | ||
); | ||
@@ -135,4 +137,4 @@ ``` | ||
controller.signal('appMounted', | ||
SetLoading, | ||
SetTitle | ||
setLoading, | ||
setTitle | ||
); | ||
@@ -161,10 +163,10 @@ | ||
import CheckSomething from './actions/CheckSomething.js'; | ||
import SetSuccessMessage from './actions/SetSuccessMessage.js'; | ||
import SetErrorMessage from './actions/SetErrorMessage.js'; | ||
import checkSomething from './actions/checkSomething.js'; | ||
import setSuccessMessage from './actions/setSuccessMessage.js'; | ||
import setErrorMessage from './actions/setErrorMessage.js'; | ||
controller.signal('appMounted', | ||
ChooseColor, { | ||
success: [SetSuccessMessage], | ||
error: [SetErrorMessage] | ||
chooseColor, { | ||
success: [setSuccessMessage], | ||
error: [setErrorMessage] | ||
} | ||
@@ -181,11 +183,13 @@ ); | ||
import LoadUser from './actions/LoadUser.js'; | ||
import SetUser from './actions/SetUser.js'; | ||
import SetError from './actions/SetError.js'; | ||
import loadUser from './actions/loadUser.js'; | ||
import setUser from './actions/setUser.js'; | ||
import setError from './actions/setError.js'; | ||
controller.signal('appMounted', | ||
[LoadUser, { | ||
success: [SetUser], | ||
error: [SetError] | ||
}] | ||
[ | ||
loadUser, { | ||
success: [setUser], | ||
error: [setError] | ||
} | ||
] | ||
); | ||
@@ -199,18 +203,18 @@ ``` | ||
import LoadUser from './actions/LoadUser.js'; | ||
import SetUser from './actions/SetUser.js'; | ||
import SetError from './actions/SetError.js'; | ||
import LoadProjects from './actions/LoadProjects.js'; | ||
import SetProjects from './actions/SetProjects.js'; | ||
import SetProjectsError from './actions/SetProjectsError.js'; | ||
import loadUser from './actions/loadUser.js'; | ||
import setUser from './actions/setUser.js'; | ||
import setUserError from './actions/setUserError.js'; | ||
import loadProjects from './actions/loadProjects.js'; | ||
import setProjects from './actions/setProjects.js'; | ||
import setProjectsError from './actions/setProjectsError.js'; | ||
controller.signal('appMounted', | ||
[ | ||
LoadUser, { | ||
success: [SetUser], | ||
error: [SetError] | ||
loadUser, { | ||
success: [setUser], | ||
error: [setUserError] | ||
}, | ||
LoadProjects, { | ||
success: [SetProjects], | ||
error: [SetProjectsError] | ||
loadProjects, { | ||
success: [setProjects], | ||
error: [setProjectsError] | ||
} | ||
@@ -225,3 +229,3 @@ ] | ||
```js | ||
function MyAction (args, state, output) { | ||
function myAction (input, state, output) { | ||
if (state.get('isCool')) { | ||
@@ -238,6 +242,6 @@ output.foo(); | ||
// to the default output path | ||
MyAction.defaultOutput = 'foo'; | ||
MyAction.outputs = ['foo', 'bar']; | ||
myAction.defaultOutput = 'foo'; | ||
myAction.outputs = ['foo', 'bar']; | ||
export default MyAction; | ||
export default myAction; | ||
``` | ||
@@ -249,5 +253,3 @@ | ||
```js | ||
import {Types} from './controller.js'; | ||
function MyAction (args, state, output) { | ||
function myAction (input, state, output) { | ||
output({foo: 'bar'}); | ||
@@ -257,25 +259,42 @@ }; | ||
// Define what args you expect to be received on this action | ||
MyAction.input = { | ||
isCool: Types.Bool | ||
myAction.input = { | ||
isCool: String | ||
}; | ||
// If the action only has one output | ||
MyAction.output = { | ||
foo: Types.String | ||
myAction.output = { | ||
foo: String | ||
}; | ||
// If having multiple outputs | ||
MyAction.outputs = { | ||
myAction.outputs = { | ||
success: { | ||
result: Types.Object | ||
result: Object | ||
}, | ||
error: { | ||
message: Types.String | ||
message: String | ||
} | ||
}; | ||
export default MyAction; | ||
export default myAction; | ||
``` | ||
The following types are available: **String, Number, Bool, Object, Array, Any**. | ||
The following types are available: **String, Number, Boolean, Object, Array**, its the default type constructors in JavaScript. | ||
#### Custom Types | ||
You can use a function instead. That allows you to use any typechecker. | ||
```js | ||
function myAction (input, state, output) { | ||
output({foo: 'bar'}); | ||
}; | ||
// Define what args you expect to be received on this action | ||
myAction.input = { | ||
isCool: function (value) { | ||
return typeof value === 'string' || typeof value === 'number'; | ||
}, | ||
isNotCool: MyTypeChecker.isString | ||
}; | ||
```` | ||
#### Groups | ||
@@ -282,0 +301,0 @@ By using ES6 syntax you can easily create groups of actions that can be reused. |
module.exports = function (type, value) { | ||
var types = [ | ||
String, | ||
Number, | ||
Array, | ||
Object, | ||
Boolean | ||
]; | ||
if (type === String && typeof value !== 'string') { | ||
@@ -23,3 +31,3 @@ return false; | ||
if (typeof type === 'function') { | ||
if (types.indexOf(type) === -1 && typeof type === 'function') { | ||
return type(value); | ||
@@ -26,0 +34,0 @@ } |
@@ -104,3 +104,3 @@ var Lib = require('./../src/index.js'); | ||
action.output = { | ||
foo: Lib.Types.String | ||
foo: String | ||
}; | ||
@@ -122,3 +122,3 @@ ctrl.signal('test', action, function () { | ||
action.output = { | ||
foo: Lib.Types.String | ||
foo: String | ||
}; | ||
@@ -141,3 +141,3 @@ ctrl.signal('test', action, function () { | ||
foo: { | ||
bar: Lib.Types.String | ||
bar: String | ||
} | ||
@@ -160,3 +160,3 @@ }; | ||
action.output = { | ||
foo: Lib.Types.String | ||
foo: String | ||
}; | ||
@@ -179,3 +179,3 @@ ctrl.signal('test', action, function () { | ||
foo: { | ||
bar: Lib.Types.String | ||
bar: String | ||
} | ||
@@ -391,3 +391,3 @@ }; | ||
action.input = { | ||
foo: Lib.Types.String | ||
foo: String | ||
}; | ||
@@ -394,0 +394,0 @@ ctrl.signal('test', function (args, state, next) { |
@@ -121,1 +121,7 @@ var Lib = require('./../src/index.js'); | ||
}; | ||
exports['should handle falsy values'] = function (test) { | ||
test.ok(types(String, '')); | ||
test.ok(types(Boolean, false)); | ||
test.done(); | ||
}; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1941951
25205
406