Skip to content

Commit

Permalink
Add .decorator() method (#61)
Browse files Browse the repository at this point in the history
Co-authored-by: Sindre Sorhus <[email protected]>
Co-authored-by: Federico <[email protected]>
  • Loading branch information
3 people authored Mar 18, 2021
1 parent b1c65cd commit 528fa42
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 7 deletions.
47 changes: 46 additions & 1 deletion index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ const mem = <

cache.set(key, {
data: result,
maxAge: maxAge ? Date.now() + maxAge : Infinity
maxAge: maxAge ? Date.now() + maxAge : Number.POSITIVE_INFINITY
});

return result;
Expand All @@ -140,6 +140,51 @@ const mem = <

export = mem;

/**
@returns A TypeScript decorator which memoizes the given function.
@example
```
import mem = require('mem');
class Example {
index = 0
@mem.decorator()
counter() {
return ++this.index;
}
}
class ExampleWithOptions {
index = 0
@mem.decorator({maxAge: 1000})
counter() {
return ++this.index;
}
}
```
*/
mem.decorator = <
FunctionToMemoize extends AnyFunction,
CacheKeyType
>(
options: Options<FunctionToMemoize, CacheKeyType> = {}
) => (
target: any,
propertyKey: string,
descriptor: PropertyDescriptor
): void => {
const input = target[propertyKey];

if (typeof input !== 'function') {
throw new TypeError('The decorated value must be a function');
}

descriptor.value = mem(input, options);
};

/**
Clear all cached data of a memoized function.
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@
"@ava/typescript": "^1.1.1",
"@sindresorhus/tsconfig": "^0.7.0",
"@types/serialize-javascript": "^4.0.0",
"ava": "^3.13.0",
"ava": "^3.15.0",
"del-cli": "^3.0.1",
"delay": "^4.4.0",
"serialize-javascript": "^5.0.1",
"tsd": "^0.13.1",
"typescript": "^4.0.3",
"xo": "^0.33.1"
"xo": "^0.38.2"
},
"ava": {
"files": [
Expand Down
32 changes: 32 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,38 @@ Use a different cache storage. Must implement the following methods: `.has(key)`

Refer to the [caching strategies](#caching-strategy) section for more information.

### mem.decorator(options)

Returns a TypeScript decorator which memoizes the given function.

#### options

Type: `object`

Same as options for `mem()`.

```js
const mem = require('mem');

class Example {
index = 0

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

class ExampleWithOptions {
index = 0

@mem.decorator({maxAge: 1000})
counter() {
return ++this.index;
}
}
```

### mem.clear(fn)

Clear all cached data of a memoized function.
Expand Down
2 changes: 1 addition & 1 deletion test-d/index.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ mem((text: string) => Boolean(text), {

mem(() => 1, {
cacheKey: arguments_ => {
expectType<[]>(arguments_);
expectType<[]>(arguments_); // eslint-disable-line @typescript-eslint/ban-types
}
});

Expand Down
22 changes: 20 additions & 2 deletions test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,9 @@ test('.clear()', t => {

test('prototype support', t => {
class Unicorn {
i = 0;
index = 0;
foo() {
return this.i++;
return this.index++;
}
}

Expand All @@ -237,6 +237,24 @@ test('prototype support', t => {
t.is(unicorn.foo(), 0);
});

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

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

const alpha = new TestClass();
t.is(alpha.counter(), 1);
t.is(alpha.counter(), 1, 'The method should be memoized');

const beta = new TestClass();
t.is(beta.counter(), 1, 'The method should not be memoized across instances');
});

test('mem.clear() throws when called with a plain function', t => {
t.throws(() => {
mem.clear(() => {});
Expand Down
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"extends": "@sindresorhus/tsconfig",
"compilerOptions": {
"outDir": "dist"
"outDir": "dist",
"experimentalDecorators": true
},
"files": [
"index.ts",
Expand Down

0 comments on commit 528fa42

Please sign in to comment.