Skip to content

Commit

Permalink
Don't use the same memoized function across instances when `.decorato…
Browse files Browse the repository at this point in the history
…r()` is used (#75)
  • Loading branch information
Richienb committed Apr 20, 2021
1 parent a7e8b18 commit d21357c
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 7 deletions.
17 changes: 15 additions & 2 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import mapAgeCleaner = require('map-age-cleaner');

type AnyFunction = (...arguments_: any) => any;

const decoratorInstanceMap = new WeakMap();

const cacheStore = new WeakMap<AnyFunction>();

interface CacheStorageContent<ValueType> {
Expand Down Expand Up @@ -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
```
Expand Down Expand Up @@ -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);
};
};

/**
Expand Down
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
10 changes: 6 additions & 4 deletions test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,21 +238,23 @@ test('prototype support', t => {
});

test('.decorator()', t => {
class TestClass {
index = 0;
let returnValue = 1;

class TestClass {
@mem.decorator()
counter() {
return ++this.index;
return returnValue;
}
}

const alpha = new TestClass();
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 => {
Expand Down

0 comments on commit d21357c

Please sign in to comment.