-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
compose.js
91 lines (74 loc) · 2.23 KB
/
compose.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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
'use strict'
module.exports = function compose () {
const layers = []
function shell (location, options, callback) {
if (typeof location === 'function') {
callback = location
options = {}
location = null
} else if (typeof location === 'object' && location !== null) {
callback = options
options = location
location = null
}
if (typeof options === 'function') {
callback = options
options = {}
} else if (typeof options !== 'object' || options === null) {
options = {}
}
return layers.reduce(function (db, layer, index) {
if (index < layers.length - 1) {
return layer(db, options)
} else {
// Last layer takes an optional open-callback
db = layer(db, options, callback)
// Transitional utility.
// If db is levelup, it will auto-open and call the callback. If
// abstract-leveldown, it won't. If abstract-db (a concept), it might.
if (callback && !isLevelup(db) && db.status === 'new') {
db.open(Object.assign({}, layer.defaults, options), function (err) {
if (err) return callback(err)
callback(null, db)
})
}
return db
}
}, location)
}
shell.use = function (layer, defaults) {
if (Array.isArray(layer)) {
for (let i = 0; i < layer.length; i++) {
shell.use(layer[i], Object.assign({}, isOpts(layer[i + 1]) && layer[++i], defaults))
}
return shell
}
layers.push(function wrapped (db, options, callback) {
wrapped.defaults = defaults
return layer(db, Object.assign({}, defaults, options), callback)
})
decorate(shell, layer)
return shell
}
shell.errors = null
shell.use(Array.prototype.slice.call(arguments))
return shell
}
function decorate (shell, nut) {
if (nut.errors) {
shell.errors = nut.errors
}
for (const m of ['destroy', 'repair']) {
if (typeof nut[m] === 'function') {
shell[m] = function (...args) {
nut[m](...args)
}
}
}
}
function isLevelup (db) {
return typeof db === 'object' && db !== null && /^levelup$/i.test(db)
}
function isOpts (o) {
return o == null || (typeof o === 'object' && !Array.isArray(o))
}