vlio20 / utils-decorators

Decorators for web and node applications
https://vlio20.github.io/utils-decorators/
MIT License
218 stars 13 forks source link

Provide context to the keyResolver function (target and propertyName) #150

Closed scaljeri closed 1 year ago

scaljeri commented 2 years ago

Thanks a lot for this very nice collection of decorators!

I noticed that the Memoize has a config-property keyResolver on which you can define a function that only receives the values of function parameters. However, in my case I would like to be able to ignore one or more argument (using another decorator)

DEMO

Because the keyResolve has no clue what the target or function(name) is that is being called there seems to be no way of doing this with the memoize decorator. Is my assumption right or can I work around this issue somehow?

If all is not possible, I would like to propose a feature request, that the keyResolver is executed with a context. Something like this

const context = { target, propertyName, .... };
keyResolver.call(context, arguments);

Probably a very bad idea, but you never know :)

Cheers

vlio20 commented 2 years ago

Hi @scaljeri, I am currently on a family vacation. I will take a look as soon as I will return (2 weeks approximately)

vlio20 commented 2 years ago

Hi @scaljeri, if I understand your intention correctly, you are trying to provide the keyResolver with some extra data (context). If you wish to have access to the context you could pass a method name (is more info documentation).

Here is an example (taken from a unit test) https://github.com/vlio20/utils-decorators/blob/master/src/memoize/memoize.spec.ts#L126

scaljeri commented 2 years ago

Hi @vlio20 In that code example. foo and fooWithInnerMapper are both part of the same class. So yes, inside foo you can probably do what I want (not complete sure). But if you look at my Stackblitz, I would like to create a generic decorator. But maybe I missed the point, so maybe you can modify my stackblitz and demonstrate how to do what I'm looking for.

vlio20 commented 2 years ago

I have to say that I do not fully understand your proposal. If you want to ignore specific arguments why not just do something like that:

keyResolver: (a: number, b: number, c: numer) => `${a}_${b}`

In this example, I am ignoring a.

scaljeri commented 2 years ago

In my demo I have the following

import { Cached } from './cache-decorator';
import { CachedParamIgnore } from './cache-param-ignore';

class Example3 {
    @Cached({ expirationTimeMs: 4000 })
    fibo(@CachedParamIgnore() n: number, x?: number): number {
        console.log('calculate for ', n);

        if (n < 2) return 1;

       return this.fibo(n - 1) + this.fibo(n - 2);
   }
}

const test = new Example3();

test.fibo(5, 9));
test.fibo(5, 9));

file

Inside that Cached decorator (file) I have that keyResolver function. It doesn't know anything about Example3 or which parameter you want to ignore. Hope this makes more sense :)