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

meld

Package Overview
Dependencies
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

meld - npm Package Compare versions

Comparing version 1.1.0 to 1.2.0

aspect/cache.js

21

docs/api.md

@@ -13,2 +13,4 @@ # meld.js API

1. [Removing Method Advice](#removing-method-advice)
1. [Accessing the Joinpoint](#accessing-the-joinpoint)
* [meld.joinpoint](#meldjoinpoint)
1. [Constructor-specific Info](#constructor-specific-info)

@@ -179,4 +181,6 @@

Meld.js allows you to add any number of advices to a method, function, or constructor. In addition to adding them individually, as [shown here](api.md#advising-methods), using the individual advice methods (e.g. meld.before, meld.after, etc.), you can also add several advices at once using `meld.add()`.
Meld.js allows you to add any number of advices to a method, function, or constructor. In addition to adding them individually, as [shown here](#advising-methods), using the individual advice methods (e.g. meld.before, meld.after, etc.), you can also add several advices at once using `meld.add()`.
For example, the [bundled aspects](aspects.md) are implemented this way, and can be added using `meld.add()`.
## meld.add

@@ -215,2 +219,17 @@

# Accessing the Joinpoint
[Around advice](#meldaround) receives the current [joinpoint](reference.md#joinpoint) as a parameter. Other advice types can use `meld.joinpoint()` to retrieve the current joinpoint.
## meld.joinpoint
```js
function myBeforeAdvice() {
var joinpoint = meld.joinpoint();
// Use joinpoint fields as necessary
}
```
**IMPORTANT:** The returned joinpoint is only valid within the advice function where it was retrieved by calling `meld.joinpoint`. You should not cache the joinpoint returned by `meld.joinpoint()` and attempt to use it outside of an advice function, or in different advice functions from that which it was originally retrieved.
# Constructor-specific Info

@@ -217,0 +236,0 @@

@@ -11,3 +11,5 @@ # meld.js Reference

* [Around](#around)
* [Joinpoint](#joinpoint)
1. [Joinpoint](#joinpoint)
1. [Accessing the Joinpoint](#accessing-the-joinpoint)
2. [Around Joinpoint](#around-joinpoint)
1. [Advice Order](#advice-order)

@@ -108,8 +110,34 @@ 1. [Advising Methods](#advising-methods)

Around advice receives a [Joinpoint](#joinpoint) as its only parameter, which it can use to access the original arguments, context, and method name of the original function, as well as allow the original function to continue, with either its original arguments, or a modified list of arguments.
Around advice receives an [Around Joinpoint](#around-joinpoint) as its only parameter, which it can use to access the original arguments, context, and method name of the original function, as well as allow the original function to continue, with either its original arguments, or a modified list of arguments.
### Joinpoint
# Joinpoint
A joinpoint is the point at which a method or function was intercepted. Think of it as a description of the original function invocation. It provides the arguments with which the original method was called, the method name (in the case of an object method), and its own methods for allowing the original method call to continue and getting its result.
A joinpoint is the point at which a method or function was intercepted. Think of it as a description of the original function invocation. It provides the arguments with which the original method was called, the method name (in the case of an object method), and the context with which the method was called.
A joinpoint has the following properties:
* target - context with which the original method was called
* method - String name of the method that was called
* args - Array of arguments that were passed to the method
## Accessing the Joinpoint
Around advice always receives the current [around joinpoint](#around-joinpoint) as its only argument.
From *inside* any other advice type (before, after, etc.) you may access the current joinpoint by calling `meld.joinpoint()`. It will return the joinpoint within which the current advice function is executing.
When called from *outside* an advice function, `meld.joinpoint()` always returns undefined.
**IMPORTANT:** The returned joinpoint is only valid within the advice function where it was retrieved by calling `meld.joinpoint`. You should not cache the joinpoint returned by `meld.joinpoint()` and attempt to use it outside of an advice function, or in different advice functions from that which it was originally retrieved.
## Around Joinpoint
Around advice receives as its only argument, an augmented joinpoint, sometimes called a "proceeding joinpoint". It has the same fields as a regular joinpoint, with the addition of "proceed" methods for allowing the original method call to continue and getting its result.
An around joinpoint has the following additional properties:
* proceed() - function that around advice should call to proceed to the original method invocation. You may pass arguments to `proceed()` and they will be used *instead of* the original arguments. It will return the result of the original method, or throw an exception if the original method throws.
* proceedApply:`Function` - similar to `proceed()` but accepts an Array of new arguments, e.g. `proceedApply([1, 2, 3])` is equivalent to `proceed(1, 2, 3)`
* proceedCount() - function that returns the number of times that `proceed()` and/or `proceedApply()` have been called *within the current around advice*.
# Advice Order

@@ -116,0 +144,0 @@

132

meld.js

@@ -12,3 +12,3 @@ /** @license MIT License (c) copyright B Cavalier & J Hann */

*
* @version 1.1.0
* @version 1.2.0
*/

@@ -18,6 +18,32 @@ (function (define) {

var ap, prepend, append, iterators, slice, isArray, defineProperty, freeze;
freeze = Object.freeze || function (o) { return o; };
var meld, currentJoinpoint, joinpointStack,
ap, prepend, append, iterators, slice, isArray, defineProperty;
//
// Public API
//
meld = {
// General add aspect
// Returns a function that will remove the newly-added aspect
add: addAspect,
// Add a single, specific type of advice
// returns a function that will remove the newly-added advice
before: adviceApi('before'),
around: adviceApi('around'),
on: adviceApi('on'),
afterReturning: adviceApi('afterReturning'),
afterThrowing: adviceApi('afterThrowing'),
after: adviceApi('after'),
// Access to the current joinpoint in advices
joinpoint: joinpoint
};
// TOOD: Freeze joinpoints when v8 perf problems are resolved
// freeze = Object.freeze || function (o) { return o; };
joinpointStack = [];
ap = Array.prototype;

@@ -63,3 +89,3 @@ prepend = ap.unshift;

advised = this.advised = function() {
var context, args, callOrig, result, afterType, exception;
var context, joinpoint, args, callOrig, afterType;

@@ -92,23 +118,36 @@ // If called as a constructor (i.e. using "new"), create a context

advisor._callSimpleAdvice('before', context, args);
// Save the previous joinpoint and set the current joinpoint
joinpoint = pushJoinpoint({
target: context,
method: func,
args: args
});
try {
result = advisor._callAroundAdvice(context, func, args, callOrigAndOn);
} catch(e) {
result = exception = e;
// Switch to afterThrowing
afterType = 'afterThrowing';
}
advisor._callSimpleAdvice('before', context, args);
args = [result];
try {
joinpoint.result = advisor._callAroundAdvice(context, func, args, callOrigAndOn);
} catch(e) {
joinpoint.result = joinpoint.exception = e;
// Switch to afterThrowing
afterType = 'afterThrowing';
}
callAfter(afterType, args);
callAfter('after', args);
args = [joinpoint.result];
if(exception) {
throw exception;
callAfter(afterType, args);
callAfter('after', args);
if(joinpoint.exception) {
throw joinpoint.exception;
}
return joinpoint.result;
} finally {
// Restore the previous joinpoint, if necessary.
popJoinpoint();
}
return result;
function callOrigAndOn(args) {

@@ -191,3 +230,4 @@ var result = callOrig(args);

// Joinpoint is immutable
joinpoint = freeze({
// TODO: Use Object.freeze once v8 perf problem is fixed
joinpoint = pushJoinpoint({
target: context,

@@ -201,4 +241,8 @@ method: method,

// Call supplied around advice function
return around.call(context, joinpoint);
try {
// Call supplied around advice function
return around.call(context, joinpoint);
} finally {
popJoinpoint();
}

@@ -293,3 +337,3 @@ /**

* @param methodName {String} name of method on target for which to get an advisor
* @return {Object} existing or newly created advisor for the supplied method
* @return {Object|undefined} existing or newly created advisor for the supplied method
*/

@@ -318,21 +362,2 @@ Advisor.get = function(target, methodName) {

//
// Public API
//
return {
// General add aspect
// Returns a function that will remove the newly-added aspect
add: addAspect,
// Add a single, specific type of advice
// returns a function that will remove the newly-added advice
before: adviceApi('before'),
around: adviceApi('around'),
on: adviceApi('on'),
afterReturning: adviceApi('afterReturning'),
afterThrowing: adviceApi('afterThrowing'),
after: adviceApi('after')
};
function addAspect(target, pointcut, aspect) {

@@ -510,3 +535,4 @@ // pointcut can be: string, Array of strings, RegExp, Function(targetObject): Array of strings

try {
Object.defineProperty(instance, 'constructor', {
// Try to define a constructor, but don't care if it fails
defineProperty(instance, 'constructor', {
value: C,

@@ -536,7 +562,19 @@ enumerable: false

function joinpoint() {
return currentJoinpoint;
}
function pushJoinpoint(newJoinpoint) {
joinpointStack.push(currentJoinpoint);
return currentJoinpoint = newJoinpoint;
}
function popJoinpoint() {
return currentJoinpoint = joinpointStack.pop();
}
return meld;
});
})(typeof define == 'function' && define.amd
? define
: function (factory) { module.exports = factory(); }
// Boilerplate for AMD and CommonJS
})(typeof define == 'function' && define.amd ? define : function (factory) { module.exports = factory(); }
);
{
"name": "meld",
"version": "1.1.0",
"version": "1.2.0",
"description": "AOP for JS with before, around, on, afterReturning, afterThrowing, after advice, and pointcut support",

@@ -5,0 +5,0 @@ "keywords": ["aop", "aspect", "cujo"],

@@ -30,2 +30,3 @@ [![Build Status](https://secure.travis-ci.org/cujojs/meld.png)](http://travis-ci.org/cujojs/meld)

* [Reference](meld/blob/master/docs/reference.md)
* [Aspects](meld/blob/master/docs/aspects.md)

@@ -76,2 +77,10 @@ # Quick Start

### 1.2.0
* `meld.joinpoint()` - [Access the current joinpoint](meld/blob/master/docs/api.md#meldjoinpoint) from any advice type.
* [Bundled aspects](meld/blob/master/docs/aspects.md):
* trace: trace method call entry/return/throw
* memoize: simple memoization for methods and functions
* cache: configurable caching aspect to do more than simple memoization
### 1.1.0

@@ -78,0 +87,0 @@

@@ -1,3 +0,3 @@

(function(buster, aop) {
"use strict";
(function(buster, meld) {
'use strict';

@@ -35,3 +35,3 @@ var assert, refute;

aop.after(target, 'method', function afterAdvice(a) {
meld.after(target, 'method', function afterAdvice(a) {
// this should be the advised object

@@ -64,3 +64,3 @@ assert.equals(target, this);

aop.after(target, 'method', function afterAdvice(a) {
meld.after(target, 'method', function afterAdvice(a) {
// this should be the advised object

@@ -67,0 +67,0 @@ assert.equals(target, this);

@@ -1,3 +0,3 @@

(function(buster, aop) {
"use strict";
(function(buster, meld) {
'use strict';

@@ -31,3 +31,3 @@ var assert, refute, fail;

aop.afterReturning(target, 'method', function afterAdvice(a) {
meld.afterReturning(target, 'method', function afterAdvice(a) {
// this should be the advised object

@@ -65,3 +65,3 @@ assert.equals(target, this);

aop.afterReturning(target, 'method', function afterReturning0(a) {
meld.afterReturning(target, 'method', function afterReturning0(a) {
// this should be the advised object

@@ -86,3 +86,3 @@ assert.equals(target, this);

aop.afterReturning(target, 'method', function afterReturning1(a) {
meld.afterReturning(target, 'method', function afterReturning1(a) {
// this should be the advised object

@@ -104,3 +104,3 @@ assert.equals(target, this);

aop.afterReturning(target, 'method', function afterReturning2(a) {
meld.afterReturning(target, 'method', function afterReturning2(a) {
// this should be the advised object

@@ -137,3 +137,3 @@ assert.equals(target, this);

aop.afterReturning(target, 'method', spy);
meld.afterReturning(target, 'method', spy);

@@ -140,0 +140,0 @@ assert.exception(function() {

@@ -1,3 +0,3 @@

(function(buster, aop) {
"use strict";
(function(buster, meld) {
'use strict';

@@ -31,3 +31,3 @@ var assert, refute, fail;

aop.afterThrowing(target, 'method', function afterReturning1(a) {
meld.afterThrowing(target, 'method', function afterReturning1(a) {
// this should be the advised object

@@ -62,3 +62,3 @@ assert.equals(target, this);

aop.afterThrowing(target, 'method', function afterReturning0(a) {
meld.afterThrowing(target, 'method', function afterReturning0(a) {
// this should be the advised object

@@ -83,3 +83,3 @@ assert.equals(target, this);

aop.afterThrowing(target, 'method', function afterReturning1(a) {
meld.afterThrowing(target, 'method', function afterReturning1(a) {
// this should be the advised object

@@ -101,3 +101,3 @@ assert.equals(target, this);

aop.afterThrowing(target, 'method', function afterReturning2(a) {
meld.afterThrowing(target, 'method', function afterReturning2(a) {
// this should be the advised object

@@ -132,3 +132,3 @@ assert.equals(target, this);

aop.afterThrowing(target, 'method', spy);
meld.afterThrowing(target, 'method', spy);

@@ -135,0 +135,0 @@ refute.exception(function() {

@@ -1,3 +0,3 @@

(function(buster, aop) {
"use strict";
(function(buster, meld) {
'use strict';

@@ -17,3 +17,3 @@ var assert, refute;

Fixture.prototype = {
method: function(a) {
method: function() {
return (++this.val);

@@ -30,3 +30,3 @@ }

aop.around(target, 'method', function aroundAdvice(joinpoint) {
meld.around(target, 'method', function aroundAdvice(joinpoint) {
// this should be the advised object

@@ -64,3 +64,3 @@ assert.equals(target, this);

aop.around(target, 'method', function aroundAdvice(joinpoint) {
meld.around(target, 'method', function aroundAdvice(joinpoint) {
// Calling joinpoint.proceed() multiple times is allowed

@@ -78,10 +78,9 @@ assert.same(0, joinpoint.proceedCount());

'should be invoked from most recently added to least recently added': function() {
var inner, outer, target;
var inner, target;
inner = this.spy();
outer = this.spy();
target = new Fixture();
// Inner
aop.around(target, 'method', function aroundAdviceInner(joinpoint) {
meld.around(target, 'method', function aroundAdviceInner(joinpoint) {
inner();

@@ -93,3 +92,3 @@ // This will proceed to the original method

// Outer
aop.around(target, 'method', function aroundAdviceOuter(joinpoint) {
meld.around(target, 'method', function aroundAdviceOuter(joinpoint) {
refute.calledOnce(inner);

@@ -116,3 +115,3 @@ // This will proceed to the inner around

aop.around(target, 'method', function aroundAdvice(joinpoint) {
meld.around(target, 'method', function aroundAdvice(joinpoint) {
// arg should be the return value from the orig method

@@ -142,3 +141,3 @@ assert.equals(1, joinpoint.args.length);

aop.around(target, 'method', function aroundAdvice(joinpoint) {
meld.around(target, 'method', function aroundAdvice(joinpoint) {
// arg should be the return value from the orig method

@@ -163,3 +162,3 @@ assert.equals(1, joinpoint.args.length);

aop.around(target, 'method', function aroundAdvice(joinpoint) {
meld.around(target, 'method', function aroundAdvice(joinpoint) {
joinpoint.proceed();

@@ -178,3 +177,3 @@ return 1;

aop.around(target, 'method', function aroundAdvice(joinpoint) {
meld.around(target, 'method', function aroundAdvice(/*joinpoint*/) {
// Don't proceed to original method

@@ -181,0 +180,0 @@ // joinpoint.proceed();

@@ -1,3 +0,3 @@

(function(buster, aop) {
"use strict";
(function(buster, meld) {
'use strict';

@@ -26,3 +26,3 @@ var assert, refute;

aop.before(target, 'method', function before1(a) {
meld.before(target, 'method', function before1(a) {
// this should be the advised object

@@ -56,3 +56,3 @@ assert.equals(target, this);

aop.before(target, 'method', function before0(a) {
meld.before(target, 'method', function before0(a) {
assert.equals(target, this);

@@ -71,3 +71,3 @@ assert.equals(arg, a);

aop.before(target, 'method', function before1(a) {
meld.before(target, 'method', function before1(a) {
assert.equals(target, this);

@@ -90,3 +90,3 @@ assert.equals(arg, a);

aop.before(target, 'method', function before2(a) {
meld.before(target, 'method', function before2(a) {
assert.equals(target, this);

@@ -93,0 +93,0 @@ assert.equals(arg, a);

exports['meld:node'] = {
environment: 'node',
tests: ['*.js']
tests: ['**/*.js']
};
(function(buster, meld) {
"use strict";
'use strict';

@@ -4,0 +4,0 @@ var assert, refute, arg;

(function(buster, meld) {
"use strict";
'use strict';

@@ -4,0 +4,0 @@ var assert, refute;

@@ -1,3 +0,3 @@

(function(buster, aop) {
"use strict";
(function(buster, meld) {
'use strict';

@@ -32,3 +32,3 @@ var assert, refute;

aop.on(target, 'method', function on(a) {
meld.on(target, 'method', function on(a) {
// this should be the advised object

@@ -61,3 +61,3 @@ assert.equals(target, this);

aop.on(target, 'method', spy);
meld.on(target, 'method', spy);

@@ -64,0 +64,0 @@ assert.exception(function() {

@@ -1,3 +0,3 @@

(function(buster, aop) {
"use strict";
(function(buster, meld) {
'use strict';

@@ -21,3 +21,3 @@ var assert, refute;

aop.add(target, 'method1', {
meld.add(target, 'method1', {
before: before

@@ -47,3 +47,3 @@ });

aop.add(target, ['method1', 'method3'], {
meld.add(target, ['method1', 'method3'], {
before: before

@@ -78,3 +78,3 @@ });

aop.add(target, /method[13]/, {
meld.add(target, /method[13]/, {
before: before

@@ -109,3 +109,3 @@ });

aop.add(target,
meld.add(target,
function(target) {

@@ -112,0 +112,0 @@ return ['method1', 'method3'];

@@ -1,3 +0,3 @@

(function(buster, aop) {
"use strict";
(function(buster, meld) {
'use strict';

@@ -19,3 +19,3 @@ var assert, refute;

// Advise the prototype method
aop.before(Fixture.prototype, 'method', before);
meld.before(Fixture.prototype, 'method', before);

@@ -22,0 +22,0 @@ target = new Fixture();

@@ -1,3 +0,3 @@

(function(buster, aop) {
"use strict";
(function(buster, meld) {
'use strict';

@@ -22,3 +22,3 @@ var assert, refute;

advice = this.spy();
ref = aop.before(fixture, 'method', advice);
ref = meld.before(fixture, 'method', advice);

@@ -46,3 +46,3 @@ assert.defined(fixture.method._advisor);

advice = this.spy();
ref = aop.before(fixture, /method[12]/, advice);
ref = meld.before(fixture, /method[12]/, advice);

@@ -73,3 +73,3 @@ assert.defined(fixture.method1._advisor);

ref = aop.around(fixture, 'method', advice);
ref = meld.around(fixture, 'method', advice);

@@ -102,3 +102,3 @@ fixture.method();

fixture.method = this.spy();
ref = aop.add(fixture, 'method', aspect);
ref = meld.add(fixture, 'method', aspect);

@@ -105,0 +105,0 @@ fixture.method();

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