Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

dcl

Package Overview
Dependencies
Maintainers
1
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dcl - npm Package Compare versions

Comparing version 1.0.0 to 1.0.1

tests/test_counter.js

6

advices/counter.js

@@ -7,3 +7,3 @@ (function(factory){

}else{
dcl_advices_counter = factory(dcl);
dclAdvicesCounter = factory(dcl);
}

@@ -26,4 +26,4 @@ })(function(dcl){

},
after: function(r){
if(r instanceof Error){
after: function(args, result){
if(result instanceof Error){
++self.errors;

@@ -30,0 +30,0 @@ }

@@ -7,3 +7,3 @@ (function(factory){

}else{
dcl_advices_flow = factory();
dclAdvicesFlow = factory();
}

@@ -10,0 +10,0 @@ })(function(){

@@ -7,3 +7,3 @@ (function(factory){

}else{
dcl_advices_memoize = factory();
dclAdvicesMemoize = factory();
}

@@ -10,0 +10,0 @@ })(function(){

@@ -7,3 +7,3 @@ (function(factory){

}else{
dcl_advices_time = factory();
dclAdvicesTime = factory();
}

@@ -10,0 +10,0 @@ })(function(){

@@ -7,3 +7,3 @@ (function(factory){

}else{
dcl_advices_trace = factory();
dclAdvicesTrace = factory();
}

@@ -16,3 +16,3 @@ })(function(){

if(n == 1){ return ch; }
var h = rep(Math.floor(n / 2));
var h = rep(ch, Math.floor(n / 2));
return h + h + ((n & 1) ? ch : "");

@@ -32,5 +32,6 @@

},
after: function(r){
after: function(args, result){
console.log((level ? pad(lvl, 2 * lvl) : "") + this + " => " +
name + (r && r instanceof Error ? " throws" : " returns") + " " + r);
name + (result && result instanceof Error ? " throws" : " returns") +
" " + result);
--lvl;

@@ -37,0 +38,0 @@ }

@@ -7,3 +7,3 @@ (function(factory){

}else{
Mixer = factory(dcl);
dclBasesMixer = factory(dcl);
}

@@ -10,0 +10,0 @@ })(function(dcl){

@@ -7,3 +7,3 @@ (function(factory){

}else{
Replacer = factory(dcl);
dclBasesReplacer = factory(dcl);
}

@@ -10,0 +10,0 @@ })(function(dcl){

@@ -7,3 +7,3 @@ (function(factory){

}else{
dcl_debug = factory(dcl, advise);
dclDebug = factory(dcl, advise);
}

@@ -33,5 +33,6 @@ })(function(dcl, advise){

var chainNames = ["UNCHAINED BUT CONTAINS ADVICE(S)", "CHAINED BEFORE", "CHAINED AFTER"];
var chainNames = ["UNCHAINED BUT CONTAINS ADVICE(S)", "CHAINED BEFORE", "CHAINED AFTER",
"ERRONEOUSLY CHAINED BEFORE AND AFTER"];
function chainName(id){
return id >= 0 && id <= 2 ? chainNames[id] : "UNKNOWN";
return id >= 0 && id <= 3 ? chainNames[id] : "UNKNOWN (" + id + ")";
}

@@ -59,3 +60,3 @@

}
throw new CycleError("dcl: base class cycle found" + (cName ? " in " + cName : "") +
throw new CycleError("dcl: base class cycle found in: " + (cName || "UNNAMED") +
" - bases: " + names.join(", ") + " are mutually dependent" +

@@ -67,5 +68,5 @@ (someUnknown ? noDecls : ""));

someUnknown = !(cName && name);
throw new ChainingError("dcl: conflicting chain directives found" + (cName ? " in " + cName: "") +
" for method " + a1 + " - it is presumed to be " + chainName(a3) + " yet class " +
(name || ("UNNAMED_" + a4._u)) + "assumes it to be " + chainName(a5) +
throw new ChainingError("dcl: conflicting chain directives from bases found in: " + (cName || ("UNNAMED_" + a2._u)) +
", method: " + a1 + " - it was " + chainName(a3) + " yet " +
(name || ("UNNAMED_" + a4._u)) + " sets it to " + chainName(a5) +
(someUnknown ? noDecls : ""));

@@ -75,4 +76,4 @@ case "set chaining":

someUnknown = !cName;
throw new SetChainingError("dcl: attempt to set conflicting chain directive" + (cName ? " in " + cName: "") +
" for method " + a1 + " - it is " + chainName(a3) + " now yet being changed to " + chainName(a4) +
throw new SetChainingError("dcl: attempt to set conflicting chain directives in: " + (cName || ("UNNAMED_" + a2._u)) +
", method: " + a1 + " - it was " + chainName(a4) + " yet being changed to " + chainName(a3) +
(someUnknown ? noDecls : ""));

@@ -82,14 +83,14 @@ case "wrong super call":

someUnknown = !cName;
throw new SuperCallError("dcl: wrong argument of an around advice or supercall" +
(cName ? " in " + cName: "") + " for method " + a2 + (someUnknown ? noDecls : ""));
throw new SuperCallError("dcl: argument of around advice or supercall decorator should be a function in: " +
(cName || ("UNNAMED_" + a1._u)) + ", method: " + a2 + (someUnknown ? noDecls : ""));
case "wrong super":
cName = a1.prototype.hasOwnProperty("declaredClass") && a1.prototype.declaredClass;
someUnknown = !cName;
throw new SuperError("dcl: super method should be a function" +
(cName ? " in " + cName: "") + " for method " + a2 + (someUnknown ? noDecls : ""));
throw new SuperError("dcl: super method should be a function in: " +
(cName || ("UNNAMED_" + a1._u)) + ", method: " + a2 + (someUnknown ? noDecls : ""));
case "wrong super result":
cName = a1.prototype.hasOwnProperty("declaredClass") && a1.prototype.declaredClass;
someUnknown = !cName;
throw new SuperResultError("dcl: around advice or supercall should return a function" +
(cName ? " in " + cName: "") + " for method " + a2 + (someUnknown ? noDecls : ""));
throw new SuperResultError("dcl: around advice or supercall should return a function in: " +
(cName || ("UNNAMED_" + a1._u)) + ", method: " + a2 + (someUnknown ? noDecls : ""));
}

@@ -96,0 +97,0 @@ throw new DclError("dcl: " + reason);

@@ -41,5 +41,5 @@ (function(factory){

}
if(i >= 0){ // intentional assignments
if(i >= 0){
for(++i, l = bases.length; i < l; ++i){
if((meta = (base = bases[i])._m)){ // intentional assignment
if((meta = (base = bases[i])._m)){ // intentional assignments
if((meta = meta.h).hasOwnProperty(name)){ // intentional assignment

@@ -75,6 +75,7 @@ return meta[name];

ctor.prototype.inherited = inherited;
ctor.prototype.getInherited = get;
});
inherited.get = get;
dcl.getInherited = inherited.get = get;
return dcl.inherited = inherited; // intentional assignment
});

@@ -96,5 +96,5 @@ (function(factory){

// create stubs
// create stubs with fake constructor
o = {b: bases, h: props, w: r, c: {}};
bases[0] = {_m: o}; // fake constructor (only meta is available)
bases[0] = {_m: o, prototype: proto};
buildStubs(o, proto);

@@ -165,3 +165,3 @@ ctor = proto[cname];

for(; f = chain[i]; ++i){
if(isSuper(f)){ // intentional assignment
if(isSuper(f)){
p = chain[i] = dcl._f(f, p, name);

@@ -168,0 +168,0 @@ }else{

@@ -7,3 +7,3 @@ (function(factory){

}else{
Cleanup = factory(dcl, Destroyable);
dclMixinsCleanup = factory(dcl, dclMixinsDestroyable);
}

@@ -10,0 +10,0 @@ })(function(dcl, Destroyable){

@@ -7,3 +7,3 @@ (function(factory){

}else{
Destroyable = factory(dcl);
dclMixinsDestroyable = factory(dcl);
}

@@ -10,0 +10,0 @@ })(function(dcl){

{
"name": "dcl",
"version": "1.0.0",
"version": "1.0.1",
"description": "Elegant minimalistic implementation of OOP with mixins + AOP.",

@@ -5,0 +5,0 @@ "main": "dcl.js",

# DCL [![Build Status](https://secure.travis-ci.org/uhop/dcl.png?branch=master)](http://travis-ci.org/uhop/dcl)
A minimalistic yet complete JavaScript package for node.js and browsers that implements OOP with mixins + AOP at both "class" and object level. Implements C3 MRO to support a Python-like multiple inheritance, efficient supercalls, chaining, full set of advices, and provides some useful generic building blocks. The whole package comes with an extensive test set (85 tests at the time of writing) and fully compatible with the strict mode.
A minimalistic yet complete JavaScript package for [node.js](http://nodejs.org)
and modern browsers that implements OOP with mixins + AOP at both "class" and
object level. Implements [C3 MRO](http://www.python.org/download/releases/2.3/mro/)
to support a Python-like multiple inheritance, efficient supercalls, chaining,
full set of advices, and provides some useful generic building blocks. The whole
package comes with an extensive test set (111 tests at the time of writing) and
fully compatible with the strict mode.
The package was written with debuggability of your code in mind. It comes with a special debug module that explains mistakes, verifies created objects, and helps to keep track of AOP advices. Because the package uses direct static calls to super methods, you don't need to step over unnecessary stubs. In places where stubs are unavoidable (chains or advices) they are small, and intuitive.
The package was written with debuggability of your code in mind. It comes with
a special debug module that explains mistakes, verifies created objects, and helps
to keep track of AOP advices. Because the package uses direct static calls to super
methods, you don't need to step over unnecessary stubs. In places where stubs are
unavoidable (chains or advices) they are small, and intuitive.
If you migrate your code from a legacy framework that implements dynamic (rather than static) supercalls, take a look at the module "inherited" that dispatches supercalls dynamically trading off the simplicity of the code for some run-time CPU use, and a little bit less convenient debugging of such calls due to an extra stub between your methods.
If you migrate your code from a legacy framework that implements dynamic (rather
than static) supercalls, take a look at the module "inherited" that dispatches
supercalls dynamically trading off the simplicity of the code for some run-time
CPU use, and a little bit less convenient debugging of such calls due to an extra
stub between your methods.
The main hub of everything `dcl`-related is [dcljs.org](http://www.dcljs.org/),
which hosts [extensive documentation](http://www.dcljs.org/docs/).
## How to install
If you plan to use it in your [node.js](http://nodejs.org) project install it
like this:
```
npm install dcl
```
For your browser-based projects I suggest to use [volo.js](http://volojs.org):
```
volo install uhop/dcl
```
## How to use

@@ -66,3 +98,6 @@

As you can see it is trivial to define "classes" and derive them using single inheritance. Constructors are automatically chained and called from the farthest to the closest with the same arguments. Our Bureaucrat constructor ignores name, because it knows that Person will take care of it.
As you can see it is trivial to define "classes" and derive them using
single inheritance. Constructors are automatically chained and called from
the farthest to the closest with the same arguments. Our Bureaucrat constructor
ignores name, because it knows that Person will take care of it.

@@ -122,3 +157,6 @@ Now let's do a mixin.

The double function technique for a super call allows you to work directly with a next method in chain --- no intermediaries means that this call is as fast as it can be, no run-time penalties are involved during method calls, and it greatly simplifies debugging.
The double function technique for a super call allows you to work directly with
a next method in chain --- no intermediaries means that this call is as fast as
it can be, no run-time penalties are involved during method calls, and it greatly
simplifies debugging.

@@ -163,5 +201,10 @@ And, of course, our "classes" can be absolutely anonymous, like in this one-off "class":

Hmm, both `Talker` and `Sick` require the same "class" `Person`. How is it going to work? Don't worry, all duplicates are going to be eliminated by the underlying C3 MRO algorithm. Read all about it in the documentation.
Hmm, both `Talker` and `Sick` require the same "class" `Person`. How is it going
to work? Don't worry, all duplicates are going to be eliminated by the underlying
[C3 MRO](http://www.python.org/download/releases/2.3/mro/) algorithm. Read all
about it in [the documentation](http://dcljs.org/docs/).
Of course we can use an "around" advice as well, and it will behave just like a super call above. It will require the same double function technique to inject a method from a super class.
Of course we can use an "around" advice as well, and it will behave just like
a super call above. It will require the same double function technique to inject
a method from a super class.

@@ -204,3 +247,4 @@ ```js

While constructors are chained by default you can chain any methods you like. Usually it works well for lifecycle methods, and event-like methods.
While constructors are chained by default you can chain any methods you like.
Usually it works well for lifecycle methods, and event-like methods.

@@ -247,3 +291,4 @@ ```js

While class-level AOP is static, we can always advise any method dynamically, and unadvise it at will:
While class-level AOP is static, we can always advise any method dynamically,
and unadvise it at will:

@@ -315,7 +360,10 @@ ```js

Naturally "around" advices use the same double function technique to be super light-weight.
Naturally "around" advices use the same double function technique to be super
light-weight.
## Debugging helpers
There is a special module `dcl/debug` that adds better error checking and reporting for your "classes" and objects. All you need is to require it, and it will plug right in:
There is a special module `dcl/debug` that adds better error checking and reporting
for your "classes" and objects. All you need is to require it, and it will plug
right in:

@@ -326,3 +374,4 @@ ```js

In order to use it to its fullest, we should include a static class id in our "class" definitions like so:
In order to use it to its fullest, we should include a static class id in our
"class" definitions like so:

@@ -336,7 +385,14 @@ ```js

It is strongly suggested to specify `declaredClass` for every declaration in every real project.
It is strongly suggested to specify `declaredClass` for every declaration in every
real project.
This `declaredClass` can be any unique string, but by convention it should be a human-readable name of your "class", which possibly indicate where this class can be found. For example, if you follow the convention "one class per file it can be something like `"myProject/aSubDir/aFileName"`. If you define several "classes" per file you can use a following schema: `"myProject/SubDirs/FileName/ClassName"`. Remember that this name is for you, it will be reported in error messages and logs.
This `declaredClass` can be any unique string, but by convention it should be
a human-readable name of your "class", which possibly indicate where this class can
be found. For example, if you follow the convention "one class per file it can be
something like `"myProject/aSubDir/aFileName"`. If you define several "classes"
per file you can use a following schema: `"myProject/SubDirs/FileName/ClassName"`.
Remember that this name is for you, it will be reported in error messages and logs.
Yes, logs. The debug module can log constructors and objects created by those constructors:
Yes, logs. The debug module can log constructors and objects created by
those constructors:

@@ -392,10 +448,15 @@ ```js

This way we can always know that we generated correct classes, inspect static chaining and advices, and even can monitor dynamically attached/removed advices.
This way we can always know that we generated correct classes, inspect static
chaining and advices, and even can monitor dynamically attached/removed advices.
## Summary
Obviously this is a simple readme that was supposed to give an overview of `dcl`. For more details, please read the docs.
Obviously this is a simple readme that was supposed to give an overview of `dcl`.
For more details, please read [the docs](http://www.dcljs.org/docs/).
Additionally `dcl` provides a small library of predefined base classes, mixins, and useful advices. Check them out too.
Additionally `dcl` provides a small library of predefined
[base classes](http://www.dcljs.org/docs/bases/),
[mixins](http://www.dcljs.org/docs/mixins/),
and [useful advices](http://www.dcljs.org/docs/advices/). Check them out too.
Happy hacking!

@@ -19,3 +19,7 @@ // test harness

inherited = require("../inherited");
dcl_debug = require("../debug");
dclDebug = require("../debug");
dclBasesMixer = require("../bases/Mixer");
dclBasesReplacer = require("../bases/Replacer");
dclBasesReplacer = require("../bases/Replacer");
dclMixinsCleanup = require("../mixins/Cleanup");
}

@@ -31,14 +35,2 @@

function eqArrays(a, b){
if(a.length != b.length){
return false;
}
for(var i = 0, l = a.length; i < l; ++i){
if(a[i] !== b[i]){
return false;
}
}
return true;
}
function getNames(ctor){

@@ -928,2 +920,240 @@ var b = ctor._m.b, r = [];

}
},
// debug tests
function(){
"use strict";
if(typeof dclDebug != "undefined"){
var A = dcl(null, {
declaredClass: "A"
});
var B = dcl(null, {
declaredClass: "B"
});
var AB = dcl([A, B], {
declaredClass: "AB"
});
var BA = dcl([B, A], {
declaredClass: "BA"
});
try{
var Impossible = dcl([AB, BA], {
declaredClass: "Impossible"
});
submit("cycle error is triggered", false);
}catch(e){
submit("cycle error is DclError", e instanceof dclDebug.DclError);
submit("cycle error is CycleError", e instanceof dclDebug.CycleError);
}
}
},
function(){
"use strict";
if(typeof dclDebug != "undefined"){
var A = dcl(null, {
declaredClass: "A"
});
dcl.chainAfter(A, "m");
var B = dcl(null, {
declaredClass: "B"
});
dcl.chainBefore(B, "m");
try{
var ChainConflict = dcl([A, B], {
declaredClass: "ChainConflict"
});
submit("chain error is triggered", false);
}catch(e){
submit("chain error is DclError", e instanceof dclDebug.DclError);
submit("chain error is ChainingError", e instanceof dclDebug.ChainingError);
}
}
},
function(){
"use strict";
if(typeof dclDebug != "undefined"){
var A = dcl(null, {
declaredClass: "A"
});
dcl.chainAfter(A, "m");
try{
dcl.chainBefore(A, "m");
submit("set chaining error is triggered", false);
}catch(e){
submit("set chaining error is DclError", e instanceof dclDebug.DclError);
submit("set chaining error is ChainingError", e instanceof dclDebug.SetChainingError);
}
}
},
function(){
"use strict";
if(typeof dclDebug != "undefined"){
try{
var A = dcl(null, {
declaredClass: "A",
m: dcl.superCall("Should be a function, but it is a string.")
});
submit("supercall error is triggered", false);
}catch(e){
submit("supercall error is DclError", e instanceof dclDebug.DclError);
submit("supercall error is SuperCallError", e instanceof dclDebug.SuperCallError);
}
}
},
function(){
"use strict";
if(typeof dclDebug != "undefined"){
var A = dcl(null, {
declaredClass: "A",
m: 42 // not a function
});
try{
var B = dcl(A, {
declaredClass: "B",
m: dcl.superCall(function(sup){
return sup ? sup.call(this) : 0;
})
});
submit("super error is triggered", false);
}catch(e){
submit("super error is DclError", e instanceof dclDebug.DclError);
submit("super error is SuperCallError", e instanceof dclDebug.SuperError);
}
}
},
function(){
"use strict";
if(typeof dclDebug != "undefined"){
try{
var A = dcl(null, {
declaredClass: "A",
m: dcl.superCall(function(sup){
return "Instead of a function I return a string.";
})
});
submit("super result error is triggered", false);
}catch(e){
submit("super result error is DclError", e instanceof dclDebug.DclError);
submit("super result error is SuperCallError", e instanceof dclDebug.SuperResultError);
}
}
},
// dcl/bases tests
function(){
"use strict";
if(typeof dclBasesMixer != "undefined"){
var Mixer = dclBasesMixer;
var f = function(){}
var A = dcl(Mixer, {
declaredClass: "A",
a: 1,
b: "two",
c: null,
d: f
});
var x = new A({
a: 5,
b: false,
f: f
});
submit("Mixer: a is 5", x.a === 5);
submit("Mixer: b is false", x.b === false);
submit("Mixer: c is null", x.c === null);
submit("Mixer: d is f", x.d === f);
submit("Mixer: f is f", x.f === f);
}
},
function(){
"use strict";
if(typeof dclBasesReplacer != "undefined"){
var Replacer = dclBasesReplacer;
var f = function(){}
var A = dcl(Replacer, {
declaredClass: "A",
a: 1,
b: "two",
c: null,
d: f
});
var x = new A({
a: 5,
b: false,
f: f
});
submit("Replacer: a is 5", x.a === 5);
submit("Replacer: b is false", x.b === false);
submit("Replacer: c is null", x.c === null);
submit("Replacer: d is f", x.d === f);
submit("Replacer: there is no f", !("f" in x));
}
},
// dcl/mixins tests
function(){
"use strict";
if(typeof dclMixinsCleanup != "undefined"){
var Cleanup = dclMixinsCleanup;
var msgs = [];
var A = dcl(null, {
constructor: function(n){
this.n = n;
msgs.push(this.n);
},
destroy: function(){
msgs.push(-this.n);
}
});
var cleanup = function(n){
msgs.push(-n);
};
var B = dcl(Cleanup, {
constructor: function(){
var f1 = this.pushCleanup(new A(1));
this.f2 = this.pushCleanup(2, cleanup);
this.pushCleanup(new A(3));
this.pushCleanup(new A(4));
this.removeCleanup(f1);
f1();
this.popCleanup();
},
remove2: function(){
if(this.removeCleanup(this.f2)){
this.f2();
this.f2 = null;
}
},
destroy: function(){
msgs.push(-99);
}
});
var b = new B();
submit("Cleanup #1", msgs.join(",") == "1,3,4,-1,-4");
b.remove2();
submit("Cleanup #2", msgs.join(",") == "1,3,4,-1,-4,-2");
b.remove2();
submit("Cleanup #3", msgs.join(",") == "1,3,4,-1,-4,-2");
b.destroy();
submit("Cleanup #4", msgs.join(",") == "1,3,4,-1,-4,-2,-99,-3");
}
}

@@ -940,4 +1170,4 @@ ];

}catch(e){
if(isError){
exceptionFlag = true;
exceptionFlag = true;
if(typeof console != "undefined"){ // IE < 9 :-(
console.log("Unhandled exception in test #" + i + ": " + e.message);

@@ -944,0 +1174,0 @@ }

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc