Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
<<<<<<< HEAD
A state controller with its own debugger
To my surprise a lot of the feedback on Cerebral was its signaling implementation. Though it being an important concept in giving Cerebral its state control capabilities, it proves to also be a very good way to define the state flow of your application.
This fact led me to change the scope. Cerebral is now a standalone "controller" implementation. It sits between the UI and the STATE STORE of your application. On one side you define signals and actions. On the other side you define "mutation hooks". This gives Cerebral all it needs to understand the complete state flow of your application and give you some pretty cool tools to help develop complex applications.
The Cerebral Core API is a bit "low level", but extremely flexible. You can check out a few packages here that will instantly get you started with some of your favorite development tools:
To define a Controller you need somewhere to store your state. You can use whatever you want in this regard, but to gain the full power of the developer tools the state store should be immutable. This specifically allows you to move back and forth in time in the debugger and you will gain benefits in rendering optimization.
In this example we will use the immutable-store project as a state store, but freezer, baobab, immutable-js are also good alternatives.
controller.js
import {Controller, Value} from 'cerebral';
import Store from 'immutable-store';
import eventHub from './eventHub.js';
import ajax from 'ajax';
// First we define our initial state
let initialState = Store({
inputValue: '',
todos: []
});
// Then we define our current state, which initially is
// the initial state
let state = initialState;
export default Controller({
// All actions will receive an args object as first argument.
// You can add default args like different utilities etc.
defaultArgs: {
utils: {
ajax: ajax
}
},
// When Cerebral wants to reset the state, we have to
// define a method for handling that
onReset: function () {
state = initialState;
},
// Whenever a signal is done or triggers an async action it is likely that you want
// to update your UI. We do this with an event in this example
onUpdate: function () {
eventHub.emit('change', state);
},
// Actions exposes a get method to grab state, this hook
// retrieves that state. The path is always an array
onGet: function (path) {
return Value(state, path);
},
// Actions also exposes methods to mutate state. There
// are multiple hooks, though you decide which ones to use
onSet: function (path, value) {
const key = path.pop();
state = Value(state, path).set(key, value);
},
onPush: function (path, value) {
state = Value(state, path).push(value);
},
onUnset: ...,
onSplice: ...,
onConcat: ...,
onShift: ...,
onUnshift: ...,
onPop: ...,
});
When the wiring of state change and updates are set you can start to define the signals.
main.js
import controller from './controller.js';
controller.signal('appMounted');
controller.signals.appMounted();
Though signals does not do much without some actions.
main.js
import controller from './controller.js';
// All actions receives two arguments. The First are
// arguments passed when the signal is triggered and any
// values returned by a sync action or resolved/rejected by
// an async action
const setLoading = function setLoading (args, state) {
args.foo; // "bar"
state.set('isLoading', true);
};
controller.signal('appMounted', setLoading);
controller.signals.appMounted({
foo: 'bar'
});
Any action defined can become an async action. Defining arrays in signals indicates that the actions included should run async. The action will not get a third argument to resolve or reject.
const setLoading = function setLoading (args, state) {
state.set('isLoading', true);
};
const loadUser = function loadUser (args, state, promise) {
args.utils.ajax.get('/user').then(function (user) {
promise.resolve({
user: data
});
}).catch(function (errorMessage) {
promise.reject({
error: errorMessage
});
});
};
const setUser = function setUser (args, state) {
state.set('user', args.user);
};
const setError = function setError (args, state) {
state.set('error', args.error);
};
const unsetLoading = function unsetLoading (args, state) {
state.set('isLoading', false);
};
controller.signal('appMounted',
setLoading,
// The array indicates the action being run async. You can have
// multiple async actions in the array and they will run in
// parallell. The last entry in the array can be an object with
// two properties, "resolve" and "reject". Depending on the result
// of the promise either the resolve or reject actions will run
[loadUser, {
resolve: [setUser],
reject: [setError]
}],
// This action will run after loadUser and either setUser or
// setError has run
unsetLoading
);
controller.signals.appMounted();
As we know from functional programming pure functions are great! By passing any utils you need as "default args" your actions becomes pure, they being sync or async. This is great for testing! Just pass in a fake args object, fake state object and optionally a fake promise object, and verify that the action triggers the methods with the correct arguments.
TodoMVC: www.christianalfoni.com/todomvc
Read this article introducing Cerebral: Cerebral developer preview
Thanks guys!
FAQs
A state controller with its own debugger
The npm package cerebral receives a total of 3,292 weekly downloads. As such, cerebral popularity was classified as popular.
We found that cerebral demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 6 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.