Skip to content

Commit 384985e

Browse files
authored
Merge pull request #7 from kouhin/release/v2.0.0
Release/v2.0.0
2 parents a9b8dfd + 6ec7ce5 commit 384985e

File tree

5 files changed

+52
-54
lines changed

5 files changed

+52
-54
lines changed

.babelrc

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
11
{
22
"presets": [
3-
[
4-
"latest",
5-
{
6-
"es2015": {
7-
"loose": true
8-
}
9-
}
10-
],
3+
"env",
114
"stage-0"
125
],
136
"plugins": [

README.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const increment = () => {
3333
};
3434

3535
// This is a memoized action creator.
36-
const memoizeIncrement = memoize({ ttl: 100 })(increment);
36+
const memoizeIncrement = memoize({ ttl: 100 }, increment);
3737

3838
// Reducer
3939
function counter(state = 0, action) {
@@ -90,7 +90,7 @@ const fetchUserSuccess = (user) => {
9090
let creatorCalled = 0;
9191
let thunkCalled = 0;
9292

93-
const fetchUserRequest = memoize({ ttl: 1000 })((username) => {
93+
const fetchUserRequest = memoize({ ttl: 1000 }, (username) => {
9494
creatorCalled += 1;
9595
return (dispatch, getState) => {
9696
thunkCalled += 1;
@@ -129,31 +129,32 @@ Promise.all([promise1, promise2])
129129

130130
## API
131131

132-
### memoize(opts)(actionCreator)
132+
### memoize(opts, actionCreator)
133133

134134
Memoize actionCreator and returns a memoized actionCreator. When dispatch action that created by memorized actionCreator, it will returns a Promise.
135135

136136
#### Arguments
137137

138-
- `opts` _Object_
138+
- `opts` _Object | number <optional>_
139139
- `ttl` _Number|Function_: The time to live for cached action creator. When `ttl` is a function, `getState` will be passed as argument, and it must returns a number.
140140
- `enabled` _Boolean|Function_: Whether use memorized action creator or not. When `false`, cache will be ignored and the result of original action creator will be dispatched without caching. When `enabled` is a function, `getState` will be passed argument, and it must returns a boolean.
141141
- `isEqual`: arguments of action creator will be used as the map cache key. It uses lodash.isEqual to find the existed cached action creator. You can customize this function.
142+
- If `opts` is a number, the numbrer specifies the ttl.
142143

143144
#### Returns
144145

145146
- (Promise): will be resolved with the result of original actionCreator.
146147

147-
### createMemoizeMiddleware(opts)
148+
### createMemoizeMiddleware(globalOpts, disableTTL)
148149

149150
Create a redux [middleware](http://redux.js.org/docs/advanced/Middleware.html).
150151

151152
#### Arguments
152153

153-
- `opts` _Object_
154-
- disableTTL _Boolean_: The default value is `true` on server and `false` on browser. By default, cached action creator will not be evicted by setTimeout with TTL on server in order to prevent memory leak. You can enable it for test purpose.
155-
- globalOptions _Object_: Default opts for memorize().
156-
- **Default**: `{ ttl: 0, enabled: true, isEqual: lodash.isEqual }`
154+
- `globalOpts` _Object <optional>_
155+
- _Object_: Default opts for memorize().
156+
- **Default**: `{ ttl: 0, enabled: true, isEqual: lodash.isEqual }`]
157+
- There is another options `disableTTL`. The default value is `true` on server and `false` on browser. By default, cached action creator will not be evicted by setTimeout with TTL on server in order to prevent memory leak. You can enable it for test purpose.
157158

158159
#### Returns
159160

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "redux-memoize",
3-
"version": "1.1.0",
3+
"version": "2.0.0",
44
"description": "Memoize action creator for redux, and let you dispatch common/thunk/promise/async action whenever you want to, without worrying about duplication",
55
"main": "lib/index.js",
66
"directories": {
@@ -45,15 +45,15 @@
4545
"babel-core": "^6.23.1",
4646
"babel-eslint": "^7.1.1",
4747
"babel-plugin-transform-runtime": "^6.23.0",
48-
"babel-preset-latest": "^6.22.0",
48+
"babel-preset-env": "^1.2.1",
4949
"babel-preset-stage-0": "^6.22.0",
5050
"chai": "^3.5.0",
5151
"eslint-config-airbnb-deps": "^14.1.0",
52-
"eslint-plugin-babel": "^4.0.1",
53-
"jest": "^18.1.0",
52+
"eslint-plugin-babel": "^4.1.1",
53+
"jest": "^19.0.2",
5454
"redux": "^3.6.0",
5555
"redux-thunk": "^2.2.0",
56-
"rimraf": "^2.5.4"
56+
"rimraf": "^2.6.1"
5757
},
5858
"dependencies": {
5959
"babel-runtime": "^6.23.0",

src/index.js

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import lodashIsEqual from 'lodash/isEqual';
44
const ACTION_TYPE = '@redux-memoize/action';
55

66
const DEFAULT_META = {
7-
ttl: 0,
7+
ttl: 200,
88
enabled: true,
99
isEqual: lodashIsEqual,
1010
};
@@ -27,18 +27,19 @@ function deepGet(map, args, isEqual) {
2727
}
2828

2929
export default function createMemoizeMiddleware(options = {}) {
30-
const opts = {
30+
const {
3131
// default disableTTL is true on server side, to prevent memory leak (use GC to remove cache)
32-
disableTTL: !canUseDOM,
33-
...options,
34-
};
32+
disableTTL = !canUseDOM,
33+
...globalOptions
34+
} = options;
35+
3536
const cache = new Map();
3637
const middleware = ({ dispatch, getState }) => next => (action) => {
3738
if (typeof action === 'object' && action.type === ACTION_TYPE) {
3839
const { fn, args } = action.payload;
3940
const { ttl, enabled, isEqual } = {
4041
...DEFAULT_META,
41-
...(options.globalOptions || {}),
42+
...globalOptions,
4243
...(action.meta || {}),
4344
};
4445
let taskCache = cache.get(fn);
@@ -55,7 +56,7 @@ export default function createMemoizeMiddleware(options = {}) {
5556
const finalTTL = typeof ttl === 'function' ? ttl(getState) : ttl;
5657
if (finalTTL) {
5758
taskCache.set(args, task);
58-
if (!opts.disableTTL) {
59+
if (!disableTTL) {
5960
setTimeout(() => {
6061
taskCache.delete(args);
6162
}, finalTTL);
@@ -81,15 +82,24 @@ export default function createMemoizeMiddleware(options = {}) {
8182
return middleware;
8283
}
8384

84-
export const memoize = options => (fn) => {
85-
if (typeof fn !== 'function') {
85+
export function memoize(opts, fn) {
86+
let func;
87+
let options;
88+
if (arguments.length < 2) {
89+
options = null;
90+
func = opts;
91+
} else {
92+
options = typeof opts === 'object' ? opts : { ttl: opts };
93+
func = fn;
94+
}
95+
if (typeof func !== 'function') {
8696
throw new Error('Not a function');
8797
}
8898
return (...args) => {
8999
const action = {
90100
type: ACTION_TYPE,
91101
payload: {
92-
fn,
102+
fn: func,
93103
args,
94104
},
95105
};
@@ -98,4 +108,4 @@ export const memoize = options => (fn) => {
98108
}
99109
return action;
100110
};
101-
};
111+
}

test/middleware.spec.js

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,23 @@ describe('memoize', () => {
1818
}
1919

2020
describe('memoize()', () => {
21-
it('memoize() must return a function', () => {
22-
expect(typeof memoize()).toBe('function');
23-
});
24-
2521
it('must throw if argument is not a function', () => {
2622
expect(() => {
27-
memoize()({});
23+
memoize({});
2824
}).toThrow();
2925
expect(() => {
30-
memoize()();
26+
memoize();
3127
}).toThrow();
3228
expect(() => {
33-
memoize()(() => {});
29+
memoize(() => {});
3430
}).not.toThrow();
3531
});
3632
});
3733

3834
describe('options', () => {
3935
it('when options is not specified, must return an action without meta', () => {
4036
const args = [1, 2, '3'];
41-
expect(memoize()(actionCreator)(...args)).toEqual({
37+
expect(memoize(actionCreator)(...args)).toEqual({
4238
type: '@redux-memoize/action',
4339
payload: {
4440
fn: actionCreator,
@@ -51,7 +47,7 @@ describe('memoize', () => {
5147
const args = [1, 2, '3'];
5248
expect(memoize({
5349
ttl: 100,
54-
})(actionCreator)(...args)).toEqual({
50+
}, actionCreator)(...args)).toEqual({
5551
type: '@redux-memoize/action',
5652
payload: {
5753
fn: actionCreator,
@@ -65,7 +61,7 @@ describe('memoize', () => {
6561
const ttl = getState => getState().ttl;
6662
expect(memoize({
6763
ttl,
68-
})(actionCreator)(...args)).toEqual({
64+
}, actionCreator)(...args)).toEqual({
6965
type: '@redux-memoize/action',
7066
payload: {
7167
fn: actionCreator,
@@ -82,7 +78,7 @@ describe('memoize', () => {
8278
const isEqual = (args1, args2) => (args1 === args2);
8379
expect(memoize({
8480
isEqual,
85-
})(actionCreator)(...args)).toEqual({
81+
}, actionCreator)(...args)).toEqual({
8682
type: '@redux-memoize/action',
8783
payload: {
8884
fn: actionCreator,
@@ -192,7 +188,7 @@ describe('unit test', () => {
192188
return state;
193189
}
194190
}
195-
const createThunk = memoize({ ttl: 200 })((num) => {
191+
const createThunk = memoize({ ttl: 200 }, (num) => {
196192
thunkCreatorCalled += 1;
197193
return {
198194
type: 'INCREMENT',
@@ -234,7 +230,7 @@ describe('unit test', () => {
234230
return state;
235231
}
236232
}
237-
const createThunk = memoize({ ttl: 50 })(num => ({
233+
const createThunk = memoize({ ttl: 50 }, num => ({
238234
type: 'INCREMENT',
239235
payload: num,
240236
}));
@@ -298,16 +294,14 @@ describe('unit test', () => {
298294
return state;
299295
}
300296
}
301-
const createThunk = memoize()(num => ({
297+
const createThunk = memoize(num => ({
302298
type: 'INCREMENT',
303299
payload: num,
304300
}));
305301

306302
const memoizeMiddleware = createMemoizeMiddleware({
307303
disableTTL: false,
308-
globalOptions: {
309-
ttl: 50,
310-
},
304+
ttl: 50,
311305
});
312306

313307
const store = applyMiddleware(
@@ -371,7 +365,7 @@ describe('unit test', () => {
371365
return state;
372366
}
373367
}
374-
const createThunk = memoize({ ttl: 200 })((num) => {
368+
const createThunk = memoize({ ttl: 200 }, (num) => {
375369
thunkCreatorCalled += 1;
376370
return (dispatch) => {
377371
thunkCalled += 1;
@@ -428,7 +422,7 @@ describe('unit test', () => {
428422
return state;
429423
}
430424
}
431-
const createThunk = memoize({ ttl: 100 })((num) => {
425+
const createThunk = memoize({ ttl: 100 }, (num) => {
432426
thunkCreatorCalled += 1;
433427
return (dispatch) => {
434428
thunkCalled += 1;
@@ -526,7 +520,7 @@ describe('unit test', () => {
526520
const enabled = getState().memoizeEnabled;
527521
return enabled === undefined ? true : enabled;
528522
},
529-
})((num) => {
523+
}, (num) => {
530524
incrementCalled += 1;
531525
return {
532526
type: 'INCREMENT',
@@ -584,7 +578,7 @@ describe('unit test', () => {
584578
const ttl = getState().ttl;
585579
return typeof ttl === 'undefined' ? 0 : ttl;
586580
},
587-
})((num) => {
581+
}, (num) => {
588582
incrementCalled += 1;
589583
return {
590584
type: 'INCREMENT',

0 commit comments

Comments
 (0)