Skip to content

Commit 5d5c179

Browse files
committed
publish: add (memoize) supports getters
1 parent 8e89172 commit 5d5c179

File tree

7 files changed

+91
-13
lines changed

7 files changed

+91
-13
lines changed

lib/memd.js

+11-2
Original file line numberDiff line numberDiff line change
@@ -1047,12 +1047,21 @@ var memoize_1 = _src_fn_memoize;
10471047
function deco_memoize(opts) {
10481048
return function (target, propertyKey, descriptor) {
10491049
var viaProperty = descriptor == null;
1050-
var fn = memoize_1.fn_memoize(viaProperty ? target[propertyKey] : descriptor.value, opts, propertyKey);
1050+
var isGetter = !viaProperty && typeof descriptor.get === 'function';
1051+
var innerFn = viaProperty
1052+
? target[propertyKey]
1053+
: (isGetter ? descriptor.get : descriptor.value);
1054+
var fn = memoize_1.fn_memoize(innerFn, opts, propertyKey);
10511055
if (viaProperty) {
10521056
target[propertyKey] = fn;
10531057
return;
10541058
}
1055-
descriptor.value = fn;
1059+
if (isGetter) {
1060+
descriptor.get = fn;
1061+
}
1062+
else {
1063+
descriptor.value = fn;
1064+
}
10561065
return descriptor;
10571066
};
10581067
}

package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"name": "Alexander Kit",
66
"email": "alex.kit@atmajs.com"
77
},
8-
"version": "0.3.3",
8+
"version": "0.3.5",
99
"main": "./lib/memd.js",
1010
"types": "./lib/memd.d.ts",
1111
"repository": {
@@ -75,7 +75,8 @@
7575
"typescript": {
7676
"compilerOptions": {
7777
"#if (TEST)": {
78-
"module": "AMD"
78+
"module": "AMD",
79+
"target": "es2020"
7980
}
8081
}
8182
}

readme.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ import { deco } from 'memd';
1515

1616
class Foo {
1717
@deco.memoize()
18-
foo () {}
18+
someMethod () {}
19+
20+
@deco.memoize()
21+
get someProp () {}
1922

2023
@deco.debounce()
2124
bar () {}
@@ -57,7 +60,12 @@ const cache = new Cache(<ICacheOpts> { maxAge: 60 });
5760

5861
```ts
5962
interface IMemoizeOpts {
63+
// Per default method or getter returns are cached for all instances of a class.
64+
// Use `perInstance` to cache per instance: this could be useful when the method reads `this.` values.
6065
perInstance?: boolean
66+
67+
// When a promise is memoized, and gets rejected. Clear also the cache, so that
68+
// the next time it wont hit the cache and is reavaluated.
6169
clearOnReject?: boolean
6270
}
6371
.memoize(opts?: ICacheOpts & IMemoizeOpts)

src/deco/memoize.ts

+13-3
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,22 @@ export function deco_memoize (opts?: ICacheOpts & IMemoizeOpts) {
55

66
return function (target, propertyKey, descriptor?) {
77
const viaProperty = descriptor == null;
8-
const fn = fn_memoize(viaProperty ? target[propertyKey] : descriptor.value, opts, propertyKey);
8+
const isGetter = !viaProperty && typeof descriptor.get === 'function';
9+
10+
const innerFn = viaProperty
11+
? target[propertyKey]
12+
: (isGetter ? descriptor.get : descriptor.value);
13+
14+
const fn = fn_memoize(innerFn, opts, propertyKey);
915
if (viaProperty) {
1016
target[propertyKey] = fn;
1117
return;
1218
}
13-
descriptor.value = fn;
19+
if (isGetter) {
20+
descriptor.get = fn;
21+
} else {
22+
descriptor.value = fn;
23+
}
1424
return descriptor;
1525
};
16-
}
26+
}

test/memoize.spec.ts

+42-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { class_EventEmitter } from 'atma-utils'
22
import { deco_memoize } from '../src/deco/memoize';
3-
import sinon = require('sinon');
43
import { fn_memoize } from '../src/fn/memoize';
4+
import * as sinon from 'sinon';
55

66
UTest({
77
'memoize'() {
@@ -155,6 +155,47 @@ UTest({
155155
let result3 = await promise3;
156156
eq_(result3, 3);
157157
},
158+
159+
'memoize on properties': {
160+
'for all instances' () {
161+
class Foo {
162+
@deco_memoize()
163+
get getFoo () {
164+
return { t: Math.random() };
165+
}
166+
}
167+
let foo = new Foo ();
168+
let v1 = foo.getFoo;
169+
let v2 = foo.getFoo;
170+
eq_(typeof v1.t, 'number');
171+
eq_(v1.t, v2.t);
172+
173+
let foo2 = new Foo()
174+
let v21 = foo2.getFoo;
175+
eq_(v1.t, v21.t);
176+
},
177+
'per instance' () {
178+
class Foo {
179+
@deco_memoize({ perInstance: true })
180+
get getFoo () {
181+
return { t: Math.random() };
182+
}
183+
}
184+
let foo = new Foo ();
185+
let v1 = foo.getFoo;
186+
let v2 = foo.getFoo;
187+
eq_(typeof v1.t, 'number');
188+
eq_(v1.t, v2.t);
189+
190+
let foo2 = new Foo()
191+
let v21 = foo2.getFoo;
192+
let v22 = foo2.getFoo;
193+
eq_(typeof v21.t, 'number');
194+
eq_(v21.t, v22.t);
195+
196+
notEq_(v1.t, v21.t);
197+
}
198+
}
158199
})
159200

160201
async function wait(ms) {

tsconfig-build.json

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
{
2-
"extends": "./tsconfig.json",
3-
"files": ["src/export.ts"]
4-
}
2+
"files": ["src/export.ts"],
3+
"exclude": ["node_modules"],
4+
"compilerOptions": {
5+
"outDir": "ts-temp",
6+
"declaration": true,
7+
"sourceMap": false,
8+
"experimentalDecorators": true,
9+
"moduleResolution": "node"
10+
}
11+
}

tsconfig.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
"outDir": "ts-temp",
55
"declaration": true,
66
"sourceMap": false,
7-
"experimentalDecorators": true
7+
"experimentalDecorators": true,
8+
"moduleResolution": "node",
9+
"target": "ES2020"
810
}
911
}

0 commit comments

Comments
 (0)