Sandbox
Sandbox implementation with permission management for modular architecture
- Crossbrowser (IE8+)/Crossplatform
- tested with ~100% coverage
- support for event-driven architecture
- order of listeners and notifications doesn't matter, data will be cached and cache will be cleaned (when message is delivered or by timeout/debounce) - really useful for AMD and upcoming ES6 modules
- parent-siblings-child permissions management via grant/revoke
- sandbox can be destroyed to free resources
- if you plan to use sandbox as data proxy you can immutable plain arrays/objects by default
- caching strategies can be defined on various levels
- familiar API
License
Installation:
bower install simple-permissions
npm install simple-permissions
Tests:
To launch tests you have to run npm install
then npm test
.
If you want to contribute make sure to run grunt githooks
first thing after clone.
It will create pre-commit hook and run tests and jshint before you commit.
Please use git flow - create a feature branch for your feature and send a pull request to dev.
Please don't include dist folder in your commit.
API:
/** * constructs a sandbox * @param * @param * @name Sandbox */ {} /** * returns sandbox instance name * @return */Sandboxprototype {};/** * sets sandbox specific settings for cache adjustments, etc * @param */Sandboxprototype {};/** * Settings example (those are defaults) */var defaultSettings = cache: store: true expire: 0 //off debounce: true ;/** * creates a new Sandbox instance, changes current parent, so that Sandbox constructor can create * parent-child relations * @return */Sandboxprototype {};/** * returns immutable sandbox instance data * @return */Sandboxprototype {};/** * subscribes handler to event * @param * @param * @param */Sandboxprototype {};/** * unsubscribes handlers from event * @param */Sandboxprototype {};/** * emits event with given data * @param * @param */Sandboxprototype {};/** * @see emit */Sandboxprototypetrigger = Sandboxprototypeemit; /** * grants permissions * @param * @param {Object.<String, String[]>} permissionsMap permissions map */Sandboxprototype {to permissionsMap} /** * revokes permissions * @param * @param {Object.<String, String[]>} permissionsMap permissions map */Sandboxprototype {from permissionsMap} /** * frees resources by removing links to private and info data */Sandboxprototype {};
Examples:
//anonymousvar a = ;aname; //random string //namedvar bar = 'BAR';barname; //'BAR' //datavar bar = 5;bardata; //5 //named with datavar bar = 'BAR' 5;barname; //'BAR'bardata; //5 //plain objects or arrays are immutablevar x = a: 10;var bar = x;bardataa; //10bardataa = 20;bardataa; //20xa; //10 //after destroyvar x = 5;x;xdata; //throws Sandbox exception //children sandboxes creationvar appSandbox = 'APP';var moduleASandbox = appSandbox;var moduleBSandbox = appSandbox;var moduleAASandbox = moduleASandbox;//but following will throw, because siblings should have unique namesvar moduleAlphaSandbox = appSandbox;
Subscribe/publish and caching
var foo = ;var test = value: 'abc' { return thisvalue; } ;foo;foo; //testListener was called with this set to test objectfoo; //un-subscribed //order doesn't matter, can subscribe late (even after emit) and you'll still get datafoo;foo;; //event expiration time for event debounce by default (also possible to set expiration settings for sandbox instance)var foo = 'FOO';foo;foo;foo; //will be called right away;;; //get default caching settingsvar defaults = Sandbox; //{cache: {store: true, expire: 0, debounce: true}}//set caching settings globallySandbox;foo;foo;;; //no store settingsSandbox;var foo = 'FOO';foo;foo; //hello will not executefoo; //hello will be called
Permissions management
//setup codevar Parent = 'Parent' a: 1 b: 2 ;var Father = Parent;var Mother = Parent;var Son = Mother; //sandbox can get data from itselfParent;Parent; //listener called onceParent; //listener called second time, listener2 called onceParent; //unsubscribeParent; //nothing changed //kids from parents - no permissions:Father;Parent; //Father's listener didn't execute because of lack of permissions //kids from parents - with permissions://grant Father and Mother permissions to get events from Parent's ping eventParent;Father;Mother;Parent //will call listener twice (for Father and Mother) //revoke permissions ; //listener call count didn't change //kids from kids - no permissions:Father;Mother; //Father's listener didn't execute because of lack of permissions //kids from kids - with permissions://grant Father access to Mother's ping and grant Mother access to Father's pong :)Parent ;Father;Mother;Mother; //called right awayFather; //called right away//revoke permissionsParent ;Mother; //nothing happensFather; //nothing happens //parents from kids - no permissionsMother;Son; //Father's listener didn't execute because of lack of permissions //parents from kids - with permissions//grant Mother permissions to Son's ping and subscribeMother ;Son; //listener was calledMother //revoke permissions ;Son; //nothing
Real world example
When populate cities module gets new cities data, initialize popup links in different module
//in core.jsvar coreSandbox = 'Core';; ; //inside search-bar.js//...sandbox;//... //inside populate-cities.js//...sandbox;//...
Check tests and source for more