Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Structr is a framework with the following goals:
Node.js:
npm install structr
var EventEmitter = require("events").EventEmitter,
structr = require("structr");
/**
* create a mouse class which extends the node.js event emitter
*/
var Mouse = structr(EventEmitter, {
/**
*/
"__construct": function() {
this._super();
//initial coords
this.move(0, 0);
},
/**
* moves the mouse
*/
"move": function(x, y) {
this.position({ x: x, y: y});
},
/**
* second version of move incase an object is provided
*/
"second move": function(position) {
this.position(position);
},
/**
* getter / setter for the position
*/
"explicit position": {
"get": function() {
return this._position;
},
"set": function(value) {
this._position = value;
this.emit("move");
}
}
});
var mouse = new Mouse();
//listen for when the mouse has moved
mouse.on("move", function() {
console.log("mouse moved!");
})
//move 100 px left, and 100 px from the top
mouse.move(100, 100);
Extends a class
var fs = require("fs"),
structr = require("structr"),
mkdirp = require("mkdirp"),
path = require("path");
//mixin the singleton plugin
structr.mixin(require("asyngleton"));
/**
* base cache interface
*/
var AbstractCache = structr({
/**
* returns a cached value
*/
"abstract get": function(key, onGet) { },
/**
* sets a cached value
*/
"abstract set": function(key, value, onSet) { }
});
/**
* memory cache
*/
var MemoryCache = AbstractCache.extend({
/**
*/
"__construct": function() {
this._collection = {};
},
/**
*/
"get": function(key, onGet) {
onGet(null, this._collection[key]);
},
/**
*/
"set": function(key, value, onSet) {
this._collection[key] = value;
if(onSet) onSet(null, value);
}
});
/**
*/
var FsCache = MemoryCache.extend({
/**
*/
"override __construct": function(path) {
this._path = path;
this._super();
},
/**
*/
"override set": function() {
this._super.apply(this, arguments);
this._save();
},
/**
*/
"override get": function(key, onKey) {
var _super = this._super;
//load the fs cache before getting the value - this only happens ONCE
//since _load is an asynchronous singleton.
this._load(function() {
_super(key, onKey);
});
},
/**
* saves the collection to disc
*/
"_save": function() {
if(this._saving) return;
this._saving = true;
var self = this;
//make the directory incase it doesn't exist.
this._mkdir(path.dirname(this._path), function() {
//write the json file, with the json content
fs.writeFile(self._path, JSON.parse(self._collection), function(err result) {
//give some time before unlocking the save method.
//We don't want to hit fs.write on each set
setTimeout(function() {
self._saving = false;
}, 2000);
});
});
},
/**
* loads the fs cache into memory
*/
"singleton _load": function(onLoad) {
try {
this._collection = require(this._path);
} catch(e) {
//do nothing - the file doesn't exist
}
onLoad();
},
/**
* makes the fs cache directory incase it's nested. Only happens ONCE on save.
*/
"singleton _mkdir": function(onMkdir) {
mkdirp(path.dirname(this._path), onMkdir);
}
});
var cache = new FsCache(__dirname + "/test.json");
cache.get("name", function(err, name) {
if(name) {
return console.log("hello %s!", name);
}
cache.set("name", "craig", function() {
console.log("saved!");
});
});
Methods overridden have access to the _super property.
"override __construct": function ()
{
this._super();
}
Faster if you don't plan on using _super.
"__construct": function ()
{
//cannot access _super __construct
}
Overloading methods allows you to write methods which are mapped out depending on the number of parameters used. You must provide your own identifier (it could be anything) for each overloaded method, otherwise you'll simply be overwriting methods. For this example, I separate methods based on their order, e.g. one
, two
, three
, etc.
var Person = Structr({
"sayHello": function (name, callback)
{
this._name = name;
this.sayHello(callback);
},
"second sayHello": function (callback)
{
callback(this.sayHello());
},
"third sayHello": function ()
{
return 'Hello ' + this._name;
}
});
var SubPerson = Person.extend({
"override sayHello": function (callback)
{
callback(this.sayHello() + " Do you like italian food?");
},
"override second sayHello": function ()
{
return "Hello " + this._name + ", how are you doing today?";
}
});
var p = new SubPerson();
p.sayHello("Craig", function(message)
{
alert(message); //Hello Craig. how are you doing today? Do you like italian food?
});
Properties, and methods set to the class versus objects instantiated.
var Singleton = Structr({
"static getInstance": function ()
{
return this._instance || (this._instance = new Singleton());
}
});
var test1 = Singleton.getInstance();
var test2 = Singleton.getInstance();
test2.name = 'Craig';
console.log(test1.name); //Craig
Both Implicit / Explicit methods are supported, however implicit getters & setters aren't supported in all browsers. Use implicit get/set if you're doing any development under a specific platform such as Node.js, or Appcelerator Titanium.
var GSTestClass = Structr({
"explicit explicitValue": {
"get": function ()
{
return this._name;
},
"set": function (value)
{
this._name = value;
}
},
"implicit implicitValue": {
"get": function ()
{
return this._name;
},
"set": function (value)
{
this._name = value;
}
},
"explicit explicitValue2":true
});
var test = new GSTestClass();
test.explicitValue('Craig');
console.log(test.explicitValue());
test.implicitValue = 'Tim';
console.log(test.implicitValue);//Tim
console.log(test.explicitValue());//Tim
test.explicitValue2('hello world');
console.log(test.explicitValue2());//hello world
Custom modifiers are considered metadata. Use them to identify how specific methods should be handled.
var MetadataTestClass = Structr({
"myCustomMetadata test": function ()
{
return "Hello Test";
}
}));
console.log(MetadataTestClass.prototype.test.myCustomMetadata); //true
###Bindable Metadata
To add. Makes a property bindable for change. Psuedocode:
var Person = Structr({
"__construct": function(name)
{
this.name(name);
Bindable.apply(this);
},
"bindable explicit name": 1
});
var person1 = new Person("craig");
//listen for any change to name
person1.name.subscribe(function(newName)
{
alert('Name changed to '+newName);
});
//on change the subscribers will be triggered
person1.name("Craig");
###Setting Metadata
To add. Easy way to store settings on the user's computer. Psuedocode:
var User = Structr({
"__construct": function ()
{
SettingManager.apply(this);
},
"login": function ()
{
//set the account info which will be saved as a cookie
this.accountInfo({ name: "Craig", last: "Condon", token: "XXXXXXXXXX" })
},
"setting explicit accountInfo": 1
});
var u = new User();
//this gets passed once
if(!u.accountInfo)
{
u.login();
}
else
{
//pulled from local computer
alert(u.accountInfo.name);
}
change _super(...) to _super({ method: [args] }), or _super('method').call(...);
FAQs
javascript class system
We found that structr demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer 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.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.