Skip to content

Commit 2cf79e4

Browse files
committed
feat: create withMiddlewares
1 parent 812e085 commit 2cf79e4

File tree

4 files changed

+98
-28
lines changed

4 files changed

+98
-28
lines changed

README.md

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
Create recursive functions with `Y-Combinator` style.
88
```js
99
import { recursive } from 'recursive-func'
10+
import memoize from 'memoize'
1011

1112
const log = next => (...args) => {
1213
const result = next(...args)
@@ -18,15 +19,18 @@ const log = next => (...args) => {
1819
return result
1920
}
2021

21-
const middlewares = [log]
22+
const sum = recursive(
23+
self => ([head = 0, ...tail]) => {
24+
return tail.length === 0
25+
? head
26+
: head + self(tail)
27+
},
28+
[memoize]
29+
)
2230

23-
const sum = recursive(self => ([head = 0, ...tail]) => {
24-
return tail.length === 0
25-
? head
26-
: head + self(tail)
27-
}, middlewares)
31+
const sumMemoized = withMiddlewares([log], sum)
2832

29-
const value = sum([1, 2, 3])
33+
const value1 = sumMemoized([1, 2, 3])
3034

3135
// third call:
3236
// Args = [[3]]
@@ -40,7 +44,13 @@ const value = sum([1, 2, 3])
4044
// Args = [[1, 2, 3]]
4145
// Result = 6
4246

43-
console.log(value) // => 6
47+
console.log(value1) // => 6
48+
49+
const value2 = sumMemoized([2, 3])
50+
51+
// don't print nothing
52+
53+
console.log(value2) // => 5
4454
```
4555

4656
[build-badge]: https://img.shields.io/travis/user/repo/master.png?style=flat-square

src/index.js

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,34 @@
1-
export { default as recursive } from './recursive'
1+
import compose from './compose'
2+
3+
const METADATA = Symbol('recursive-func@METADATA')
4+
5+
const applyMiddlewares = (middlewares, func) => (
6+
middlewares.length !== 0
7+
? compose(middlewares)(func)
8+
: func
9+
)
10+
11+
const unwrapMetadata = func => func[METADATA]
12+
13+
export const recursive = (func, middlewares = []) => {
14+
const wrapper = applyMiddlewares(
15+
middlewares,
16+
func((...args) => wrapper(...args))
17+
)
18+
19+
return Object.assign(wrapper, {
20+
[METADATA]: {
21+
func,
22+
middlewares,
23+
}
24+
})
25+
}
26+
27+
export const withMiddlewares = (middlewares, wrapper) => {
28+
const metadata = unwrapMetadata(wrapper)
29+
30+
return recursive(metadata.func, [
31+
...metadata.middlewares,
32+
...middlewares,
33+
])
34+
}

src/recursive.js

Lines changed: 0 additions & 18 deletions
This file was deleted.

tests/index-test.js

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import expect, { createSpy } from 'expect'
22

3-
import { recursive } from 'src/index'
3+
import { recursive, withMiddlewares } from 'src/index'
44

55
describe('recursive', () => {
66
let id
@@ -75,6 +75,51 @@ describe('recursive', () => {
7575
})
7676
})
7777

78+
describe('withMiddlewares([M2], recursive(F, [M1])) == recursive(F, [M1, M2])', () => {
79+
let internal
80+
let cacheMiddleware
81+
let sum1
82+
let sum2
83+
84+
beforeEach(() => {
85+
cacheMiddleware = createSpy().andCall(next => {
86+
const cache = {}
87+
88+
return (...args) => {
89+
const key = JSON.stringify(args)
90+
91+
if (!cache[key]) {
92+
cache[key] = next(...args)
93+
}
94+
95+
return cache[key]
96+
}
97+
})
98+
99+
100+
internal = createSpy().andCall((self, [head, ...tail]) => {
101+
if (tail.length === 0) return head
102+
return head + self(tail)
103+
})
104+
105+
sum1 = withMiddlewares(
106+
[cacheMiddleware],
107+
recursive(self => (...args) => {
108+
return internal(self, ...args)
109+
}),
110+
)
111+
112+
sum2 = withMiddlewares([], sum1)
113+
})
114+
115+
it('should replay middleware when call withMiddlewares', () => {
116+
sum1([1, 2, 3])
117+
sum2([1, 2, 3])
118+
119+
expect(internal.calls.length).toEqual(6)
120+
})
121+
})
122+
78123
describe('recursive(sum)([1, 2, 3])', () => {
79124
let internal
80125
let sum

0 commit comments

Comments
 (0)