starlogic v0.1.5
StarLogic
Interstellar Functional Pro-active Programming
What is it?
A superset of the following things: an event listener, a Controller from the MVC pattern, a data validator, and a framework for handling your business logic.
The API provided gives you a Router factory, so in order to use it you must execute it first to make a router.
var App = StarLogic();It has two major functions.
Add rule/route
App.addRule(rule, func);
App.addRoute(rule, func);Don't be fooled by the semantics, these functions do the exact same thing. They add a rule and function to the application stack.
A rule is an object definition that is used to compare everything that gets push through StarLogic.
The func will simply be executed given the proper rule conditions specefied.
Route/Push
App.push(BusinessObject);
App.process(BusinessObject);
App.route(BusinessObject);Same idea, this defers the business object to be compared to the rules specified with the addRule/addRoute functions.
They will executed in the same order they were added to StarLogic.
Top Level Example
I have a process that needs to update user information conditionally.
If it has no id, that must be generated first.
If the user has no specialty, set the specialty_id to 0.
If the user has an email, set must_validate to true.
If the user finally has information that isn't updated and it can update, send an ajax request.
Then update the front end given the response.Sounds pretty reasonable? I think so. Let's code these business requirements.
//using browserified bundle...
var StarLogic = require('starlogic');
//Generate your app
var App = StarLogic();
//If it has no id, that must be generated first.
App.addRule({ type: 'user', id: false }, function(obj){ obj.id = new Guid().toString(); });
//If the user has no specialty, set the specialty_id to 0.
App.addRule({ type: 'user', specialty_id: false }, function(obj){ obj.specialty_id = 0; });
//If the user has an email, set must_validate to true.
App.addRule({ type: 'user', email: /[a-z0-9][a-z\._0-9]*@[a-z0-9_]+[\.][a-z]+/i },
function(obj){ obj.must_validate = true; });
//if can_update is true...
App.addRule({ type: 'user', can_update: true }, function(BO){
//specify jQuery callback in done...
$.post('url...', BO, 'json')
.done(App.route)//pass server result to app router
//(define the rules for incoming ajax requests...)
.fail(function(){
App.route({type:'error', message: 'This is message'});
});
//update DOM here to show the process is working
});
//Our server returns a property: {from_server: true}
App.addRule({ from_server: true, type: 'user' }, function(user) {
//perform dom update complete here
});
//if the type is error and there is a message...
App.addRule({ type: 'error', message: true }, function(){
//error handling happens here
});Everything is organized now. Let's actually push a user through our application logic.
var newUser = {
type: 'user',
name: 'John Smith'
email: 'John.Smith@pat.io',
can_update: true
};
//now everything should execute given your business rules
newUser = App.push(newUser);
//App.push and App.route returns the value it was passed
console.log(newUser);
//{
// type: 'user',
// name: 'John Smith',
// email: 'John.Smith@pat.io',
// can_update: true,
// id: 'guid value here',
// specialty_id: 0,
// must_validate: true
//}Everything just magically works.
Rules for rules
Given the following rules, you can define which functions get executed by using the reference below.
var rulesAboutRules = {
'falsy': false, //if the property is falsy "if(!prop)"
'truthy': true, //if the property is truthy "if(prop)"
'isMember': NaN, //NaN specifies if the property is a member of the object (prop in BusinessObject)
'lengthGreaterThan': 9, //this property's length must be greater than or equal to 9
'lengthLessThan': -9, //this property's length must be less than or equal to 9
'execFunction': function(propVal, name){ //property value, and name are parameters
this; //is the business object itself
return true; //passes the test (evaluates truthy)
return false; //does not pass (evaluates falsy)
},
'regex': /regex/i, //performs regex.test(prop) to determine passing
'String': 'value' //performs strict equality to determine value
};Nesting routers
This is by far the easiest concept to define. Since App.route is a function that takes one parameter (your business object), you can simply pass it to another router.
var App = StarLogic();
var UserRouter = StarLogic();
//pass the route function of UserRouter to App.addRule to delegate multiple functionalities to UserRouter
App.addRule({ type: 'user' }, UserRouter.route);Data Validation Pattern
var Validator = StarLogic();
Validator.addRule({
id: isGuid, //given function isGuid
userName: 7, //has 7 characters
password: isGood //given function isGood
}, function(bo){ bo.valid = true; });
//Any time App gets a user, validate it
App.addRule({ type: 'user' }, Validator.process)
//if it's valid, do this
App.addRule({ type: 'user', valid: true }, function(){
//is valid
});
//if it's invalid, do this
App.addRule({ type: 'user', valid: false }, function(){
//is not valid
})
var x = new User(); //do something to get some data
App.process(x);
//returns xAny time your application can be defined in terms of functions and rules, StarLogic is the 8kb browserified library you really wanted.