1 | 'use strict';
|
2 | var pull = require('pull-stream')
|
3 |
|
4 | function isString (s) {
|
5 | return 'string' === typeof s
|
6 | }
|
7 |
|
8 | var isArray = Array.isArray
|
9 |
|
10 | function isObject (o) {
|
11 | return o && 'object' === typeof o && !isArray(o)
|
12 | }
|
13 |
|
14 | function isEmpty (obj) {
|
15 | for(var k in obj) return false;
|
16 | return true
|
17 | }
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 | exports.set = function (obj, path, value) {
|
28 | var _obj, _k
|
29 | for(var i = 0; i < path.length; i++) {
|
30 | var k = path[i]
|
31 | obj[k] = obj[k] || {}
|
32 | _obj = obj; _k = k
|
33 | obj = obj[k]
|
34 | }
|
35 | _obj[_k] = value
|
36 | }
|
37 |
|
38 | exports.get = function (obj, path) {
|
39 | if(isString(path)) return obj[path]
|
40 | var value
|
41 | for(var i = 0; i < path.length; i++) {
|
42 | var k = path[i]
|
43 | value = obj = obj[k]
|
44 | if(null == obj) return obj
|
45 | }
|
46 | return value
|
47 | }
|
48 |
|
49 | exports.prefix = function (obj, path) {
|
50 | var value, parent = obj
|
51 |
|
52 | for(var i = 0; i < path.length; i++) {
|
53 | var k = path[i]
|
54 | value = obj = obj[k]
|
55 | if('object' !== typeof obj) {
|
56 | return obj
|
57 | }
|
58 | parent = obj
|
59 | }
|
60 | return 'object' !== typeof value ? !!value : false
|
61 | }
|
62 |
|
63 |
|
64 | function mkPath(obj, path) {
|
65 | for(var i in path) {
|
66 | var key = path[i]
|
67 | if(!obj[key]) obj[key]={}
|
68 | obj = obj[key]
|
69 | }
|
70 |
|
71 | return obj
|
72 | }
|
73 |
|
74 | function rmPath (obj, path) {
|
75 | (function r (obj, i) {
|
76 | var key = path[i]
|
77 | if(!obj) return
|
78 | else if(path.length - 1 === i)
|
79 | delete obj[key]
|
80 | else if(i < path.length) r(obj[key], i+1)
|
81 | if(isEmpty(obj[key])) delete obj[key]
|
82 | })(obj, 0)
|
83 | }
|
84 |
|
85 | function merge (obj, _obj) {
|
86 | for(var k in _obj)
|
87 | obj[k] = _obj[k]
|
88 | return obj
|
89 | }
|
90 |
|
91 | var mount = exports.mount = function (obj, path, _obj) {
|
92 | if(!Array.isArray(path))
|
93 | throw new Error('path must be array of strings')
|
94 | return merge(mkPath(obj, path), _obj)
|
95 | }
|
96 | var unmount = exports.unmount = function (obj, path) {
|
97 | return rmPath(obj, path)
|
98 | }
|
99 |
|
100 | function isSource (t) { return 'source' === t }
|
101 | function isSink (t) { return 'sink' === t }
|
102 | function isDuplex (t) { return 'duplex' === t }
|
103 | function isSync (t) { return 'sync' === t }
|
104 | function isAsync (t) { return 'async' === t }
|
105 | function isRequest (t) { return isSync(t) || isAsync(t) }
|
106 | function isStream (t) { return isSource(t) || isSink(t) || isDuplex(t) }
|
107 |
|
108 | function abortSink (err) {
|
109 | return function (read) {
|
110 | read(err || true, function () {})
|
111 | }
|
112 | }
|
113 |
|
114 | function abortDuplex (err) {
|
115 | return {source: pull.error(err), sink: abortSink(err)}
|
116 | }
|
117 |
|
118 | exports.errorAsStream = function (type, err) {
|
119 | return (
|
120 | isSource(type) ? pull.error(err)
|
121 | : isSink(type) ? abortSink(err)
|
122 | : abortDuplex(err)
|
123 | )
|
124 | }
|
125 |
|
126 |
|
127 | exports.errorAsStreamOrCb = function (type, err, cb) {
|
128 | return (
|
129 | isRequest(type) ? cb(err)
|
130 | : isSource(type) ? pull.error(err)
|
131 | : isSink(type) ? abortSink(err)
|
132 | : cb(err), abortDuplex(err)
|
133 | )
|
134 | }
|
135 |
|
136 | exports.pipeToStream = function (type, _stream, stream) {
|
137 | if(isSource(type))
|
138 | _stream(stream)
|
139 | else if (isSink(type))
|
140 | stream(_stream)
|
141 | else if (isDuplex(type))
|
142 | pull(_stream, stream, _stream)
|
143 | }
|
144 |
|