Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
ProxyJS is a small JavaScript library that provides the ability to proxy any function or object property method. It includes an API and you can extend it with additional functionality to fit your particular use case. Enjoy!
function proxy(){
var proxyFactory = function(){
//The wrapped function to call.
var fnToCall = arguments.length === 2 ? arguments[0][arguments[1]] : arguments[0];
//A counter used to note how many times proxy has been called.
var xCalled = 0;
//An array of arrays used to note the arguments that were passed to proxy.
var argsPassed = [];
//An array whose elements note what the wrapped function returned.
var returned = [];
///
///Privileged functions used by API
///
//Returns the number of times the wrapped function was called.
var getCalledCount = function(){
return xCalled;
};
//If called with 'n' and 'n' is within bounds then returns the
//array found at argsPassed[n], otherwise returns argsPassed.
var getArgsPassed = function(){
if(arguments.length === 1 && arguments[0] >= 0 && arguments[0] < argsPassed.length){
return argsPassed[arguments[0]];
}else{
return argsPassed;
}
};
//If called with 'n' and 'n' is within bounds then returns
//value found at returned[n], otherwise returns returned.
var getReturned = function(){
if(arguments.length === 1 && arguments[0] >= 0 && arguments[0] < returned.length){
return returned[arguments[0]];
}else{
return returned;
}
};
//If 'n' is within bounds then returns an
//info object, otherwsie returns undefined.
var getData= function(n){
if(n >= 0 && n < xCalled){
var args = getArgsPassed(n);
var ret = getReturned(n);
var info = {
count: n + 1,
argsPassed: args,
returned: ret
};
return info;
}
};
//A higher order function - iterates through the collected data and
//returns the information collected for each invocation of proxy.
var dataIterator = function(callback){
for(var i = 0; i < xCalled; i++){
callback(getData(i));
}
};
//The function that is returned to the caller.
var fn = function(){
//Note the arguments that were passed for this invocation.
var args = [].slice.call(arguments);
argsPassed.push(args.length ? args : []);
//Increment the called count for this invocation.
xCalled += 1;
//Call the wrapped function noting what it returns.
var ret = fnToCall.apply(this, args);
returned.push(ret);
//Return what the wrapped function returned to the caller.
return ret;
};
///
///Exposed Lovwer level API - see Privileged functions used by API above.
///
fn.getCalledCount = getCalledCount;
fn.getArgsPassed = getArgsPassed;
fn.getReturned = getReturned;
fn.getData = getData;
///Exposed Higher Order API - see Privileged functions used by API above.
fn.dataIterator = dataIterator;
///Replaces object's method property with proxy's fn.
if(arguments.length === 2){
arguments[0][arguments[1]] = fn;
}
//Return fn to the caller.
return fn;
};
//Convert arguments to an array, call factory and returns its value to the caller.
var args = [].slice.call(arguments);
return proxyFactory.apply(null, args);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment