I made a module whose task is to proxy the methods of a class and execute functions before or after a method. But the problem we have is that when proxied methods in a class want to call each other, the proxy promise returns in the second layer. Or to put it more simply, functions that are proxied become promises if they are used inside
Code example
class Bar {
classAlias = false;
proxyHandle = {
// little hack where we save refrenece to our class inside the object
main : this,
/**
* The apply will be fired each time the function is called
* @param target Called function
* @param scope Scope from where function was called
* @param args Arguments passed to function
* @return Results of the function
*/
apply : async function (target, scope, args) {
const func_name = target.name;
// console.log('before', func_name);
// let's call some method of this class to actually check if this is the right instance
// also remember that you have to exclude methods which you are gonna use
// inside here to avoid “too much recursion” error
this.main._free.instanceCheck();
// here we bind method with our class by accessing reference to instance
const results = target.bind(this.main)(...args);
// console.log('after', func_name, results);
return results;
}
}
constructor(classAlias) {
// Get all methods of choosen class
let methods = Object.getOwnPropertyNames( Bar.prototype );
// Find and remove constructor as we don't need Proxy on it
let consIndex = methods.indexOf('constructor');
if ( consIndex > -1 ) methods.splice(consIndex, 1);
// Replace all methods with Proxy methods
methods.forEach( methodName => {
this[methodName] = new Proxy( this[methodName], this.proxyHandle );
});
this.classAlias = classAlias;
}
// easies trick to do to avoid infinite loop inside apply is to set your functions
// inside object, as getOwnPropertyNames from prototype will only get methods
_free = {
instanceCheck : () => {
// this will check if this is our Foo class
// console.log(this.classAlias);
}
}
func1() {
let test = this.func2()
console.log(test);
}
func2(){
return 'func2'
}
}
class Foo {
classAlias = false;
proxyHandle = {
// little hack where we save refrenece to our class inside the object
main : this,
/**
* The apply will be fired each time the function is called
* @param target Called function
* @param scope Scope from where function was called
* @param args Arguments passed to function
* @return Results of the function
*/
apply : function (target, scope, args) {
const func_name = target.name;
console.log('before', func_name);
// let's call some method of this class to actually check if this is the right instance
// also remember that you have to exclude methods which you are gonna use
// inside here to avoid “too much recursion” error
this.main._free.instanceCheck();
// here we bind method with our class by accessing reference to instance
const results = target.bind(this.main)(...args);
console.log('after', func_name, results);
return results;
}
}
constructor(classAlias) {
// Get all methods of choosen class
let methods = Object.getOwnPropertyNames( Foo.prototype );
// Find and remove constructor as we don't need Proxy on it
let consIndex = methods.indexOf('constructor');
if ( consIndex > -1 ) methods.splice(consIndex, 1);
// Replace all methods with Proxy methods
methods.forEach( methodName => {
this[methodName] = new Proxy( this[methodName], this.proxyHandle );
});
this.classAlias = classAlias;
}
// easies trick to do to avoid infinite loop inside apply is to set your functions
// inside object, as getOwnPropertyNames from prototype will only get methods
_free = {
instanceCheck : () => {
// this will check if this is our Foo class
// console.log(this.classAlias);
}
}
log() {
(new Bar('Proxy Class B')).func1();
}
}
/////////////////
(new Foo('Proxy Class A')).log();
output :
before log
Promise { 'func2' }
after log undefined
The reason for leaving async
in the apply function
This is because when I want to execute functions before executing the main method, they may be syncronized or synchronous, that's why
But putting async causes another problem that I mentioned
And that is nothing but the non-implementation of nested proxy functions