-
Notifications
You must be signed in to change notification settings - Fork 68
/
lens.js
54 lines (49 loc) · 1.4 KB
/
lens.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import _ from 'lodash/fp'
import {setOn} from './conversion'
// Stubs
export let functionLens = val => (...x) => {
if (!x.length) return val
val = x[0]
}
export let objectLens = val => ({
get: () => val,
set: x => {
val = x
},
})
// Lens Conversion
export let fnToObj = fn => ({
get: fn,
set: fn,
})
export let objToFn = lens => (...values) =>
values.length ? lens.set(values[0]) : lens.get()
// Lens Construction
export let lensProp = (field, source) => ({
get: () => _.get(field, source),//source[field],
set: value => {
setOn(field, value, source)
// source[field] = value
},
})
// NOTE: This used to use mapValues; however, doing so would sometimes cause issues
// in some edge cases like trying to lens state coming from an inject function
// in the mobx library. It would inadvertently cause the inject to re-run.
// Using reduce here alleviates that issue.
export let lensOf = object =>
_.reduce(
(res, key) => {
res[key] = lensProp(key, object)
return res
},
{},
_.keys(object)
)
// Lens Manipulation
export let view = lens => (lens.get ? lens.get() : lens())
export let views = lens => () => view(lens)
export let set = _.curry((val, lens) => (lens.set ? lens.set(val) : lens(val)))
export let sets = _.curry((val, lens) => () => set(val, lens))
export let flip = lens => () => set(!view(lens), lens)
export let on = sets(true)
export let off = sets(false)