Created
January 15, 2020 17:06
-
-
Save davidecavaliere/70f9f77dcef70336317cd91583bff3ad to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export function Cache(options: CacheOptions) { | |
let lastCallArguments: any[] = []; | |
return (target, propertyKey: string, descriptor) => { | |
Reflect.metadata(CacheMetadata, options)(target); | |
const originalFunction = descriptor.value; | |
target[`${propertyKey}_cached`] = new ReplaySubject(1, options.ttl); | |
descriptor.value = function(...args) { | |
// i'm not able to capture a defaulting that happens at function level | |
/* | |
ie: | |
``` | |
@Cache(...) | |
public findAll(id: number = 1) { ... } | |
``` | |
if the function is called like`service.findAll();` then args would be [] but `originalFunction` will actually call the service with [1] | |
Is there a way to capture the defaulting mechanism? | |
*/ | |
// args changed? | |
let argsNotChanged = true; | |
for (let i = 0; i < lastCallArguments.length; i++) { | |
argsNotChanged = argsNotChanged && lastCallArguments[i] == args[i]; | |
} | |
if (!argsNotChanged) { // args change | |
this[`${propertyKey}_cached`] = new ReplaySubject(1, options.ttl); | |
} | |
lastCallArguments = args; | |
const req: Observable<any> = originalFunction.apply(this, args).pipe( | |
tap((response) => { | |
this[`${propertyKey}_cached`].next(response); | |
}) | |
); | |
// despite what the documentation says i can't find that the complete is ever called | |
return race(this[`${propertyKey}_cached`], req); | |
}; | |
return descriptor; | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment