Updating memoize decorator
This commit is contained in:
@@ -1,8 +1,17 @@
|
|||||||
export function Memoize(): Function {
|
export function Memoize(propsToWatch?: string[]): Function {
|
||||||
|
const hasPropsToWatch = typeof propsToWatch !== 'undefined' && Array.isArray(propsToWatch);
|
||||||
|
if (typeof propsToWatch !== 'undefined' && !hasPropsToWatch) {
|
||||||
|
throw new Error('Somethings wrong with the propsToWatch Array');
|
||||||
|
}
|
||||||
return function(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
return function(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
||||||
const originalMethod = descriptor.value;
|
const originalMethod = descriptor.value;
|
||||||
descriptor.value = function(this: any, ...args: any[]) {
|
descriptor.value = function(this: any, ...args: any[]) {
|
||||||
const reflectKey = `${JSON.stringify(this)}_${JSON.stringify(args)}_${propertyKey}`;
|
let modelKeyPart = this;
|
||||||
|
if (hasPropsToWatch) {
|
||||||
|
const filteredEntries = Object.entries(this).filter(([k,v]) => propsToWatch.includes(k))
|
||||||
|
modelKeyPart = Object.fromEntries(filteredEntries);
|
||||||
|
}
|
||||||
|
const reflectKey = `${JSON.stringify(modelKeyPart)}_${JSON.stringify(args)}_${propertyKey}`;
|
||||||
const hasReflectData = Reflect.hasMetadata(reflectKey, target);
|
const hasReflectData = Reflect.hasMetadata(reflectKey, target);
|
||||||
|
|
||||||
if (hasReflectData) {
|
if (hasReflectData) {
|
||||||
|
|||||||
@@ -9,8 +9,32 @@ class MemoizeTestModel extends Serde<MemoizeTestModel> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MemoizeArgsTestModel extends Serde<MemoizeTestModel> {
|
||||||
|
name: string;
|
||||||
|
@Memoize() doNameRandom(t: string): string {
|
||||||
|
return this.name + t + (Math.random() * 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MemoizePropsToWatchTestModel extends Serde<MemoizePropsToWatchTestModel> {
|
||||||
|
name: string;
|
||||||
|
desc: string
|
||||||
|
@Memoize(['name']) doNameRandom(): string {
|
||||||
|
return this.name + (Math.random() * 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MemoizePropsToWatchArgsTestModel extends Serde<MemoizePropsToWatchTestModel> {
|
||||||
|
name: string;
|
||||||
|
desc: string
|
||||||
|
@Memoize(['name']) doNameRandom(t: string): string {
|
||||||
|
return this.name + t + (Math.random() * 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
describe('@Memoize() Decorator', () => {
|
describe('@Memoize() Decorator', () => {
|
||||||
it('should remember...', () => {
|
it('should remember, no args or propsToWatch', () => {
|
||||||
const testModel = new MemoizeTestModel().deserialize({
|
const testModel = new MemoizeTestModel().deserialize({
|
||||||
name: 'test model',
|
name: 'test model',
|
||||||
});
|
});
|
||||||
@@ -19,4 +43,48 @@ describe('@Memoize() Decorator', () => {
|
|||||||
const result2 = testModel.doNameRandom();
|
const result2 = testModel.doNameRandom();
|
||||||
expect(result1).toBe(result2);
|
expect(result1).toBe(result2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should remember with args, no propsToWatch', () => {
|
||||||
|
const testModel = new MemoizeArgsTestModel().deserialize({
|
||||||
|
name: 'test model',
|
||||||
|
});
|
||||||
|
|
||||||
|
const result1 = testModel.doNameRandom('t');
|
||||||
|
const result1a = testModel.doNameRandom('t');
|
||||||
|
const result2 = testModel.doNameRandom('r');
|
||||||
|
expect(result1).toBe(result1a);
|
||||||
|
expect(result1).not.toBe(result2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remember with propsToWatch, no args', () => {
|
||||||
|
const testModel = new MemoizePropsToWatchTestModel().deserialize({
|
||||||
|
name: 'test model',
|
||||||
|
desc: 'this is a desc'
|
||||||
|
});
|
||||||
|
|
||||||
|
const result1 = testModel.doNameRandom();
|
||||||
|
testModel.desc = 'this is a desc updated'
|
||||||
|
const result2 = testModel.doNameRandom();
|
||||||
|
testModel.name = 'test model updated';
|
||||||
|
const result1a = testModel.doNameRandom();
|
||||||
|
expect(result1).toBe(result2);
|
||||||
|
expect(result1).not.toBe(result1a);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remember with propsToWatch, and args', () => {
|
||||||
|
const testModel = new MemoizePropsToWatchArgsTestModel().deserialize({
|
||||||
|
name: 'test model',
|
||||||
|
desc: 'this is a desc'
|
||||||
|
});
|
||||||
|
|
||||||
|
const result1 = testModel.doNameRandom('t');
|
||||||
|
const result1a = testModel.doNameRandom('t');
|
||||||
|
testModel.desc = 'this is a desc updated'
|
||||||
|
const result2 = testModel.doNameRandom('r');
|
||||||
|
testModel.name = 'test model updated';
|
||||||
|
const result1b = testModel.doNameRandom('t');
|
||||||
|
expect(result1).not.toBe(result2);
|
||||||
|
expect(result1).toBe(result1a);
|
||||||
|
expect(result1).not.toBe(result1b);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user