diff --git a/index.ts b/index.ts index dc6c59e..7961784 100644 --- a/index.ts +++ b/index.ts @@ -4,6 +4,8 @@ import mapAgeCleaner = require('map-age-cleaner'); type AnyFunction = (...arguments_: any) => any; +const decoratorInstanceMap = new WeakMap(); + const cacheStore = new WeakMap(); interface CacheStorageContent { @@ -141,7 +143,7 @@ const mem = < export = mem; /** -@returns A TypeScript decorator which memoizes the given function. +@returns A [decorator](https://github.com/tc39/proposal-decorators) to memoize class methods or static class methods. @example ``` @@ -182,7 +184,18 @@ mem.decorator = < throw new TypeError('The decorated value must be a function'); } - descriptor.value = mem(input, options); + delete descriptor.value; + delete descriptor.writable; + + descriptor.get = function () { + if (!decoratorInstanceMap.has(this)) { + const value = mem(input, options); + decoratorInstanceMap.set(this, value); + return value; + } + + return decoratorInstanceMap.get(this); + }; }; /** diff --git a/readme.md b/readme.md index e4c6c4c..2d6377e 100644 --- a/readme.md +++ b/readme.md @@ -198,7 +198,7 @@ Refer to the [caching strategies](#caching-strategy) section for more informatio ### mem.decorator(options) -Returns a [decorator](https://github.com/tc39/proposal-decorators) to memoize class methods. +Returns a [decorator](https://github.com/tc39/proposal-decorators) to memoize class methods or static class methods. Notes: diff --git a/test.ts b/test.ts index edb8733..b34996c 100644 --- a/test.ts +++ b/test.ts @@ -238,12 +238,12 @@ test('prototype support', t => { }); test('.decorator()', t => { - class TestClass { - index = 0; + let returnValue = 1; + class TestClass { @mem.decorator() counter() { - return ++this.index; + return returnValue; } } @@ -251,8 +251,10 @@ test('.decorator()', t => { t.is(alpha.counter(), 1); t.is(alpha.counter(), 1, 'The method should be memoized'); + returnValue++; + const beta = new TestClass(); - t.is(beta.counter(), 1, 'The method should not be memoized across instances'); + t.is(beta.counter(), 2, 'The method should not be memoized across instances'); }); test('mem.clear() throws when called with a plain function', t => {