-
Notifications
You must be signed in to change notification settings - Fork 0
/
wrap.js
67 lines (57 loc) · 1.6 KB
/
wrap.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
55
56
57
58
59
60
61
62
63
64
65
66
67
const promisify = fn => (...args) => new Promise((resolve, reject) => fn(...args, (err, result) => {
if (err) return reject(new Error(err))
if (typeof result === 'string') {
result = JSON.parse(result)
}
resolve(result)
}))
const memoize = fn => {
let val
return async (...args) => {
if (!val) {
val = fn(...args)
val.catch(err => {
// allow retry after fail
val = null
})
}
return val
}
}
const oneAtATime = (fn, name) => {
let promise = Promise.resolve()
return (...args) => {
const run = () => fn(...args)
return promise = promise.then(run, run)
}
}
const promisifyObj = obj => Object.keys(obj).reduce((wrapper, key) => {
const val = obj[key]
if (typeof val === 'function') {
wrapper[key] = promisify(val.bind(obj))
} else {
wrapper[key] = val
}
return wrapper
}, {})
const validators = {
// initialize: opts => {
// if (!opts.licenseKey) throw new Error('expected base64-encoded string "licenseKey"')
// },
initialize: () => {},
scan: opts => {},
prepareDatabase: opts => {},
}
const wrapWithValidator = (fn, validate) => async (...args) => {
validate(...args)
return fn(...args)
}
export const wrap = reader => {
const wrapper = promisifyObj(reader)
const initialize = memoize(oneAtATime(wrapper.initialize))
const scan = oneAtATime(wrapper.scan)
wrapper.initialize = wrapWithValidator(initialize, validators.initialize)
wrapper.scan = wrapWithValidator(scan, validators.scan)
wrapper.prepareDatabase = wrapWithValidator(wrapper.prepareDatabase, validators.prepareDatabase)
return wrapper
}