git ssb

2+

Dominic / pull-stream



Commit cc048d2d98e1cd95038b14d5816dd19931a7b0fa

merge

Dominic Tarr committed on 5/20/2016, 8:34:35 AM
Parent: 9624740f4ee88cb0bc96ed4cc1a0c295f6cef895
Parent: 409629c0f5e18d1098c83d9c935db213242c1588

Files changed

index.jschanged
package.jsonchanged
pull.jschanged
test/compose.jschanged
sinks.jsdeleted
sinks/collect.jsadded
sinks/concat.jsadded
sinks/drain.jsadded
sinks/find.jsadded
sinks/index.jsadded
sinks/log.jsadded
sinks/on-end.jsadded
sinks/reduce.jsadded
sources.jsdeleted
sources/count.jsadded
sources/empty.jsadded
sources/error.jsadded
sources/index.jsadded
sources/infinite.jsadded
sources/keys.jsadded
sources/once.jsadded
sources/values.jsadded
throughs.jsdeleted
throughs/async-map.jsadded
throughs/filter-not.jsadded
throughs/filter.jsadded
throughs/flatten.jsadded
throughs/index.jsadded
throughs/map.jsadded
throughs/non-unique.jsadded
throughs/take.jsadded
throughs/through.jsadded
throughs/unique.jsadded
util/abort-cb.jsadded
util/keys.jsadded
util/prop.jsadded
util/tester.jsadded
index.jsView
@@ -1,4 +1,6 @@
1+'use strict'
2+
13 var sources = require('./sources')
24 var sinks = require('./sinks')
35 var throughs = require('./throughs')
46
package.jsonView
@@ -1,8 +1,8 @@
11 {
22 "name": "pull-stream",
33 "description": "minimal pull stream",
4- "version": "3.3.3",
4+ "version": "3.4.0",
55 "homepage": "https://github.com/dominictarr/pull-stream",
66 "repository": {
77 "type": "git",
88 "url": "git://github.com/dominictarr/pull-stream.git"
@@ -17,4 +17,6 @@
1717 },
1818 "author": "Dominic Tarr <dominic.tarr@gmail.com> (http://dominictarr.com)",
1919 "license": "MIT"
2020 }
21+
22+
pull.jsView
@@ -1,4 +1,6 @@
1+'use strict'
2+
13 module.exports = function pull (a) {
24 var length = arguments.length
35 if (typeof a === 'function' && a.length === 1) {
46 var args = new Array(length)
test/compose.jsView
@@ -32,9 +32,9 @@
3232 //the pipeline will become readable!
3333
3434 var read =
3535 pull(
36- pull.readArray(['billy', 'joe', 'zeke']),
36+ pull.values(['billy', 'joe', 'zeke']),
3737 pipeline
3838 )
3939
4040 t.equal('function', typeof read)
sinks.jsView
@@ -1,121 +1,0 @@
1-'use strict'
2-
3-function id (item) { return item }
4-
5-function prop (key) {
6- return (
7- 'string' == typeof key
8- ? function (data) { return data[key] }
9- : key && 'object' === typeof key && 'function' === typeof key.exec //regexp
10- ? function (data) { var v = map.exec(data); return v && v[0] }
11- : key || id
12- )
13-}
14-
15-
16-var drain = exports.drain = function (op, done) {
17- var read, abort
18-
19- function sink (_read) {
20- read = _read
21- if(abort) return sink.abort()
22- //this function is much simpler to write if you
23- //just use recursion, but by using a while loop
24- //we do not blow the stack if the stream happens to be sync.
25- ;(function next() {
26- var loop = true, cbed = false
27- while(loop) {
28- cbed = false
29- read(null, function (end, data) {
30- cbed = true
31- if(end = end || abort) {
32- loop = false
33- if(done) done(end === true ? null : end)
34- else if(end && end !== true)
35- throw end
36- }
37- else if(op && false === op(data) || abort) {
38- loop = false
39- read(abort || true, done || function () {})
40- }
41- else if(!loop){
42- next()
43- }
44- })
45- if(!cbed) {
46- loop = false
47- return
48- }
49- }
50- })()
51- }
52-
53- sink.abort = function (err, cb) {
54- if('function' == typeof err)
55- cb = err, err = true
56- abort = err || true
57- if(read) return read(abort, cb || function () {})
58- }
59-
60- return sink
61-}
62-
63-var onEnd = exports.onEnd = function (done) {
64- return drain(null, done)
65-}
66-
67-var log = exports.log = function (done) {
68- return drain(function (data) {
69- console.log(data)
70- }, done)
71-}
72-
73-var find =
74-exports.find = function (test, cb) {
75- var ended = false
76- if(!cb)
77- cb = test, test = id
78- else
79- test = prop(test) || id
80-
81- return drain(function (data) {
82- if(test(data)) {
83- ended = true
84- cb(null, data)
85- return false
86- }
87- }, function (err) {
88- if(ended) return //already called back
89- cb(err === true ? null : err, null)
90- })
91-}
92-
93-var reduce = exports.reduce = function (reduce, acc, cb) {
94-
95- return drain(function (data) {
96- acc = reduce(acc, data)
97- }, function (err) {
98- cb(err, acc)
99- })
100-
101-}
102-
103-var collect = exports.collect =
104-function (cb) {
105- return reduce(function (arr, item) {
106- arr.push(item)
107- return arr
108- }, [], cb)
109-}
110-
111-var concat = exports.concat =
112-function (cb) {
113- return reduce(function (a, b) {
114- return a + b
115- }, '', cb)
116-}
117-
118-
119-
120-
121-
sinks/collect.jsView
@@ -1,0 +1,10 @@
1+'use strict'
2+
3+var reduce = require('./reduce')
4+
5+module.exports = function collect (cb) {
6+ return reduce(function (arr, item) {
7+ arr.push(item)
8+ return arr
9+ }, [], cb)
10+}
sinks/concat.jsView
@@ -1,0 +1,9 @@
1+'use strict'
2+
3+var reduce = require('./reduce')
4+
5+module.exports = function concat (cb) {
6+ return reduce(function (a, b) {
7+ return a + b
8+ }, '', cb)
9+}
sinks/drain.jsView
@@ -1,0 +1,48 @@
1+'use strict'
2+
3+module.exports = function drain (op, done) {
4+ var read, abort
5+
6+ function sink (_read) {
7+ read = _read
8+ if(abort) return sink.abort()
9+ //this function is much simpler to write if you
10+ //just use recursion, but by using a while loop
11+ //we do not blow the stack if the stream happens to be sync.
12+ ;(function next() {
13+ var loop = true, cbed = false
14+ while(loop) {
15+ cbed = false
16+ read(null, function (end, data) {
17+ cbed = true
18+ if(end = end || abort) {
19+ loop = false
20+ if(done) done(end === true ? null : end)
21+ else if(end && end !== true)
22+ throw end
23+ }
24+ else if(op && false === op(data) || abort) {
25+ loop = false
26+ read(abort || true, done || function () {})
27+ }
28+ else if(!loop){
29+ next()
30+ }
31+ })
32+ if(!cbed) {
33+ loop = false
34+ return
35+ }
36+ }
37+ })()
38+ }
39+
40+ sink.abort = function (err, cb) {
41+ if('function' == typeof err)
42+ cb = err, err = true
43+ abort = err || true
44+ if(read) return read(abort, cb || function () {})
45+ }
46+
47+ return sink
48+}
sinks/find.jsView
@@ -1,0 +1,28 @@
1+'use strict'
2+
3+function id (e) { return e }
4+var prop = require('../util/prop')
5+var drain = require('./drain')
6+
7+module.exports = function find (test, cb) {
8+ var ended = false
9+ if(!cb)
10+ cb = test, test = id
11+ else
12+ test = prop(test) || id
13+
14+ return drain(function (data) {
15+ if(test(data)) {
16+ ended = true
17+ cb(null, data)
18+ return false
19+ }
20+ }, function (err) {
21+ if(ended) return //already called back
22+ cb(err === true ? null : err, null)
23+ })
24+}
25+
26+
27+
28+
sinks/index.jsView
@@ -1,0 +1,12 @@
1+'use strict'
2+
3+module.exports = {
4+ drain: require('./drain'),
5+ onEnd: require('./on-end'),
6+ log: require('./log'),
7+ find: require('./find'),
8+ reduce: require('./reduce'),
9+ collect: require('./collect'),
10+ concat: require('./concat')
11+}
12+
sinks/log.jsView
@@ -1,0 +1,9 @@
1+'use strict'
2+
3+var drain = require('./drain')
4+
5+module.exports = function log (done) {
6+ return drain(function (data) {
7+ console.log(data)
8+ }, done)
9+}
sinks/on-end.jsView
@@ -1,0 +1,7 @@
1+'use strict'
2+
3+var drain = require('./drain')
4+
5+module.exports = function onEnd (done) {
6+ return drain(null, done)
7+}
sinks/reduce.jsView
@@ -1,0 +1,12 @@
1+'use strict'
2+
3+var drain = require('./drain')
4+
5+module.exports = function reduce (reducer, acc, cb) {
6+ return drain(function (data) {
7+ acc = reducer(acc, data)
8+ }, function (err) {
9+ cb(err, acc)
10+ })
11+}
12+
sources.jsView
@@ -1,79 +1,0 @@
1-
2-var keys = exports.keys =
3-function (object) {
4- return values(Object.keys(object))
5-}
6-
7-function abortCb(cb, abort, onAbort) {
8- cb(abort)
9- onAbort && onAbort(abort === true ? null: abort)
10- return
11-}
12-
13-var once = exports.once =
14-function (value, onAbort) {
15- return function (abort, cb) {
16- if(abort)
17- return abortCb(cb, abort, onAbort)
18- if(value != null) {
19- var _value = value; value = null
20- cb(null, _value)
21- } else
22- cb(true)
23- }
24-}
25-
26-var values = exports.values = exports.readArray =
27-function (array, onAbort) {
28- if(!array)
29- return function (abort, cb) {
30- if(abort) return abortCb(cb, abort, onAbort)
31- return cb(true)
32- }
33- if(!Array.isArray(array))
34- array = Object.keys(array).map(function (k) {
35- return array[k]
36- })
37- var i = 0
38- return function (abort, cb) {
39- if(abort)
40- return abortCb(cb, abort, onAbort)
41- cb(i >= array.length || null, array[i++])
42- }
43-}
44-
45-
46-var count = exports.count =
47-function (max) {
48- var i = 0; max = max || Infinity
49- return function (end, cb) {
50- if(end) return cb && cb(end)
51- if(i > max)
52- return cb(true)
53- cb(null, i++)
54- }
55-}
56-
57-var infinite = exports.infinite =
58-function (generate) {
59- generate = generate || Math.random
60- return function (end, cb) {
61- if(end) return cb && cb(end)
62- return cb(null, generate())
63- }
64-}
65-
66-//a stream that ends immediately.
67-var empty = exports.empty = function () {
68- return function (abort, cb) {
69- cb(true)
70- }
71-}
72-
73-//a stream that errors immediately.
74-var error = exports.error = function (err) {
75- return function (abort, cb) {
76- cb(err)
77- }
78-}
79-
sources/count.jsView
@@ -1,0 +1,13 @@
1+'use strict'
2+
3+module.exports = function count (max) {
4+ var i = 0; max = max || Infinity
5+ return function (end, cb) {
6+ if(end) return cb && cb(end)
7+ if(i > max)
8+ return cb(true)
9+ cb(null, i++)
10+ }
11+}
12+
13+
sources/empty.jsView
@@ -1,0 +1,7 @@
1+'use strict'
2+//a stream that ends immediately.
3+module.exports = function empty () {
4+ return function (abort, cb) {
5+ cb(true)
6+ }
7+}
sources/error.jsView
@@ -1,0 +1,8 @@
1+'use strict'
2+//a stream that errors immediately.
3+module.exports = function error (err) {
4+ return function (abort, cb) {
5+ cb(err)
6+ }
7+}
8+
sources/index.jsView
@@ -1,0 +1,10 @@
1+'use strict'
2+module.exports = {
3+ keys: require('./keys'),
4+ once: require('./once'),
5+ values: require('./values'),
6+ count: require('./count'),
7+ infinite: require('./infinite'),
8+ empty: require('./empty'),
9+ error: require('./error')
10+}
sources/infinite.jsView
@@ -1,0 +1,10 @@
1+'use strict'
2+module.exports = function infinite (generate) {
3+ generate = generate || Math.random
4+ return function (end, cb) {
5+ if(end) return cb && cb(end)
6+ return cb(null, generate())
7+ }
8+}
9+
10+
sources/keys.jsView
@@ -1,0 +1,7 @@
1+'use strict'
2+var values = require('./values')
3+module.exports = function (object) {
4+ return values(Object.keys(object))
5+}
6+
7+
sources/once.jsView
@@ -1,0 +1,16 @@
1+'use strict'
2+var abortCb = require('../util/abort-cb')
3+
4+module.exports = function once (value, onAbort) {
5+ return function (abort, cb) {
6+ if(abort)
7+ return abortCb(cb, abort, onAbort)
8+ if(value != null) {
9+ var _value = value; value = null
10+ cb(null, _value)
11+ } else
12+ cb(true)
13+ }
14+}
15+
16+
sources/values.jsView
@@ -1,0 +1,21 @@
1+'use strict'
2+var abortCb = require('../util/abort-cb')
3+
4+module.exports = function values (array, onAbort) {
5+ if(!array)
6+ return function (abort, cb) {
7+ if(abort) return abortCb(cb, abort, onAbort)
8+ return cb(true)
9+ }
10+ if(!Array.isArray(array))
11+ array = Object.keys(array).map(function (k) {
12+ return array[k]
13+ })
14+ var i = 0
15+ return function (abort, cb) {
16+ if(abort)
17+ return abortCb(cb, abort, onAbort)
18+ cb(i >= array.length || null, array[i++])
19+ }
20+}
21+
throughs.jsView
@@ -1,234 +1,0 @@
1-'use strict';
2-
3-function id (item) { return item }
4-
5-function prop (key) {
6- return (
7- 'string' == typeof key
8- ? function (data) { return data[key] }
9- : 'object' === typeof key && 'function' === typeof key.exec //regexp
10- ? function (data) { var v = map.exec(data); return v && v[0] }
11- : key
12- )
13-}
14-
15-function tester (test) {
16- return (
17- 'object' === typeof test && 'function' === typeof test.test //regexp
18- ? function (data) { return test.test(data) }
19- : prop (test) || id
20- )
21-}
22-
23-var sources = require('./sources')
24-var sinks = require('./sinks')
25-
26-var map = exports.map =
27-
28-function (map) {
29- if(!map) return id
30- map = prop(map)
31- return function (read) {
32- return function (abort, cb) {
33- read(abort, function (end, data) {
34- try {
35- data = !end ? map(data) : null
36- } catch (err) {
37- return read(err, function () {
38- return cb(err)
39- })
40- }
41- cb(end, data)
42- })
43- }
44- }
45-}
46-
47-var asyncMap = exports.asyncMap =
48-function async (map) {
49- if(!map) return id
50- map = prop(map)
51- var busy = false, abortCb, aborted
52- return function (read) {
53- return function next (abort, cb) {
54- if(aborted) return cb(aborted)
55- if(abort) {
56- aborted = abort
57- if(!busy) read(abort, cb)
58- else read(abort, function () {
59- //if we are still busy, wait for the mapper to complete.
60- if(busy) abortCb = cb
61- else cb(abort)
62- })
63- }
64- else
65- read(null, function (end, data) {
66- if(end) cb(end)
67- else if(aborted) cb(aborted)
68- else {
69- busy = true
70- map(data, function (err, data) {
71- busy = false
72- if(aborted) {
73- cb(aborted)
74- abortCb(aborted)
75- }
76- else if(err) next (err, cb)
77- else cb(null, data)
78- })
79- }
80- })
81- }
82- }
83-}
84-
85-var filter = exports.filter =
86-function (test) {
87- //regexp
88- test = tester(test)
89- return function (read) {
90- return function next (end, cb) {
91- var sync, loop = true
92- while(loop) {
93- loop = false
94- sync = true
95- read(end, function (end, data) {
96- if(!end && !test(data))
97- return sync ? loop = true : next(end, cb)
98- cb(end, data)
99- })
100- sync = false
101- }
102- }
103- }
104-}
105-
106-var filterNot = exports.filterNot =
107-function (test) {
108- test = tester(test)
109- return filter(function (data) { return !test(data) })
110-}
111-
112-//a pass through stream that doesn't change the value.
113-var through = exports.through =
114-function (op, onEnd) {
115- var a = false
116-
117- function once (abort) {
118- if(a || !onEnd) return
119- a = true
120- onEnd(abort === true ? null : abort)
121- }
122-
123- return function (read) {
124- return function (end, cb) {
125- if(end) once(end)
126- return read(end, function (end, data) {
127- if(!end) op && op(data)
128- else once(end)
129- cb(end, data)
130- })
131- }
132- }
133-}
134-
135-//read a number of items and then stop.
136-var take = exports.take =
137-function (test, opts) {
138- opts = opts || {}
139- var last = opts.last || false // whether the first item for which !test(item) should still pass
140- var ended = false
141- if('number' === typeof test) {
142- last = true
143- var n = test; test = function () {
144- return --n
145- }
146- }
147-
148- return function (read) {
149-
150- function terminate (cb) {
151- read(true, function (err) {
152- last = false; cb(err || true)
153- })
154- }
155-
156- return function (end, cb) {
157- if(ended) last ? terminate(cb) : cb(ended)
158- else if(ended = end) read(ended, cb)
159- else
160- read(null, function (end, data) {
161- if(ended = ended || end) {
162- //last ? terminate(cb) :
163- cb(ended)
164- }
165- else if(!test(data)) {
166- ended = true
167- last ? cb(null, data) : terminate(cb)
168- }
169- else
170- cb(null, data)
171- })
172- }
173- }
174-}
175-
176-//drop items you have already seen.
177-var unique = exports.unique = function (field, invert) {
178- field = prop(field) || id
179- var seen = {}
180- return filter(function (data) {
181- var key = field(data)
182- if(seen[key]) return !!invert //false, by default
183- else seen[key] = true
184- return !invert //true by default
185- })
186-}
187-
188-//passes an item through when you see it for the second time.
189-var nonUnique = exports.nonUnique = function (field) {
190- return unique(field, true)
191-}
192-
193-//convert a stream of arrays or streams into just a stream.
194-var flatten = exports.flatten = function () {
195- return function (read) {
196- var _read
197- return function (abort, cb) {
198- if (abort) { //abort the current stream, and then stream of streams.
199- _read ? _read(abort, function(err) {
200- read(err || abort, cb)
201- }) : read(abort, cb)
202- }
203- else if(_read) nextChunk()
204- else nextStream()
205-
206- function nextChunk () {
207- _read(null, function (err, data) {
208- if (err === true) nextStream()
209- else if (err) {
210- read(true, function(abortErr) {
211- // TODO: what do we do with the abortErr?
212- cb(err)
213- })
214- }
215- else cb(null, data)
216- })
217- }
218- function nextStream () {
219- _read = null
220- read(null, function (end, stream) {
221- if(end)
222- return cb(end)
223- if(Array.isArray(stream) || stream && 'object' === typeof stream)
224- stream = sources.values(stream)
225- else if('function' != typeof stream)
226- stream = sources.once(stream)
227- _read = stream
228- nextChunk()
229- })
230- }
231- }
232- }
233-}
234-
throughs/async-map.jsView
@@ -1,0 +1,43 @@
1+'use strict'
2+
3+function id (e) { return e }
4+var prop = require('../util/prop')
5+
6+module.exports = function asyncMap (map) {
7+ if(!map) return id
8+ map = prop(map)
9+ var busy = false, abortCb, aborted
10+ return function (read) {
11+ return function next (abort, cb) {
12+ if(aborted) return cb(aborted)
13+ if(abort) {
14+ aborted = abort
15+ if(!busy) read(abort, cb)
16+ else read(abort, function () {
17+ //if we are still busy, wait for the mapper to complete.
18+ if(busy) abortCb = cb
19+ else cb(abort)
20+ })
21+ }
22+ else
23+ read(null, function (end, data) {
24+ if(end) cb(end)
25+ else if(aborted) cb(aborted)
26+ else {
27+ busy = true
28+ map(data, function (err, data) {
29+ busy = false
30+ if(aborted) {
31+ cb(aborted)
32+ abortCb(aborted)
33+ }
34+ else if(err) next (err, cb)
35+ else cb(null, data)
36+ })
37+ }
38+ })
39+ }
40+ }
41+}
42+
43+
throughs/filter-not.jsView
@@ -1,0 +1,9 @@
1+'use strict'
2+
3+var tester = require('../util/tester')
4+var filter = require('./filter')
5+
6+module.exports = function filterNot (test) {
7+ test = tester(test)
8+ return filter(function (data) { return !test(data) })
9+}
throughs/filter.jsView
@@ -1,0 +1,24 @@
1+'use strict'
2+
3+var tester = require('../util/tester')
4+
5+module.exports = function filter (test) {
6+ //regexp
7+ test = tester(test)
8+ return function (read) {
9+ return function next (end, cb) {
10+ var sync, loop = true
11+ while(loop) {
12+ loop = false
13+ sync = true
14+ read(end, function (end, data) {
15+ if(!end && !test(data))
16+ return sync ? loop = true : next(end, cb)
17+ cb(end, data)
18+ })
19+ sync = false
20+ }
21+ }
22+ }
23+}
24+
throughs/flatten.jsView
@@ -1,0 +1,47 @@
1+'use strict'
2+
3+var values = require('../sources/values')
4+var once = require('../sources/once')
5+
6+//convert a stream of arrays or streams into just a stream.
7+module.exports = function flatten () {
8+ return function (read) {
9+ var _read
10+ return function (abort, cb) {
11+ if (abort) { //abort the current stream, and then stream of streams.
12+ _read ? _read(abort, function(err) {
13+ read(err || abort, cb)
14+ }) : read(abort, cb)
15+ }
16+ else if(_read) nextChunk()
17+ else nextStream()
18+
19+ function nextChunk () {
20+ _read(null, function (err, data) {
21+ if (err === true) nextStream()
22+ else if (err) {
23+ read(true, function(abortErr) {
24+ // TODO: what do we do with the abortErr?
25+ cb(err)
26+ })
27+ }
28+ else cb(null, data)
29+ })
30+ }
31+ function nextStream () {
32+ _read = null
33+ read(null, function (end, stream) {
34+ if(end)
35+ return cb(end)
36+ if(Array.isArray(stream) || stream && 'object' === typeof stream)
37+ stream = values(stream)
38+ else if('function' != typeof stream)
39+ stream = once(stream)
40+ _read = stream
41+ nextChunk()
42+ })
43+ }
44+ }
45+ }
46+}
47+
throughs/index.jsView
@@ -1,0 +1,16 @@
1+'use strict'
2+
3+module.exports = {
4+ map: require('./map'),
5+ asyncMap: require('./async-map'),
6+ filter: require('./filter'),
7+ filterNot: require('./filter-not'),
8+ through: require('./through'),
9+ take: require('./take'),
10+ unique: require('./unique'),
11+ nonUnique: require('./non-unique'),
12+ flatten: require('./flatten')
13+}
14+
15+
16+
throughs/map.jsView
@@ -1,0 +1,23 @@
1+'use strict'
2+
3+function id (e) { return e }
4+var prop = require('../util/prop')
5+
6+module.exports = function map (mapper) {
7+ if(!mapper) return id
8+ mapper = prop(mapper)
9+ return function (read) {
10+ return function (abort, cb) {
11+ read(abort, function (end, data) {
12+ try {
13+ data = !end ? mapper(data) : null
14+ } catch (err) {
15+ return read(err, function () {
16+ return cb(err)
17+ })
18+ }
19+ cb(end, data)
20+ })
21+ }
22+ }
23+}
throughs/non-unique.jsView
@@ -1,0 +1,8 @@
1+'use strict'
2+
3+var unique = require('./unique')
4+
5+//passes an item through when you see it for the second time.
6+module.exports = function nonUnique (field) {
7+ return unique(field, true)
8+}
throughs/take.jsView
@@ -1,0 +1,41 @@
1+'use strict'
2+
3+//read a number of items and then stop.
4+module.exports = function take (test, opts) {
5+ opts = opts || {}
6+ var last = opts.last || false // whether the first item for which !test(item) should still pass
7+ var ended = false
8+ if('number' === typeof test) {
9+ last = true
10+ var n = test; test = function () {
11+ return --n
12+ }
13+ }
14+
15+ return function (read) {
16+
17+ function terminate (cb) {
18+ read(true, function (err) {
19+ last = false; cb(err || true)
20+ })
21+ }
22+
23+ return function (end, cb) {
24+ if(ended) last ? terminate(cb) : cb(ended)
25+ else if(ended = end) read(ended, cb)
26+ else
27+ read(null, function (end, data) {
28+ if(ended = ended || end) {
29+ //last ? terminate(cb) :
30+ cb(ended)
31+ }
32+ else if(!test(data)) {
33+ ended = true
34+ last ? cb(null, data) : terminate(cb)
35+ }
36+ else
37+ cb(null, data)
38+ })
39+ }
40+ }
41+}
throughs/through.jsView
@@ -1,0 +1,23 @@
1+'use strict'
2+
3+//a pass through stream that doesn't change the value.
4+module.exports = function through (op, onEnd) {
5+ var a = false
6+
7+ function once (abort) {
8+ if(a || !onEnd) return
9+ a = true
10+ onEnd(abort === true ? null : abort)
11+ }
12+
13+ return function (read) {
14+ return function (end, cb) {
15+ if(end) once(end)
16+ return read(end, function (end, data) {
17+ if(!end) op && op(data)
18+ else once(end)
19+ cb(end, data)
20+ })
21+ }
22+ }
23+}
throughs/unique.jsView
@@ -1,0 +1,18 @@
1+'use strict'
2+
3+function id (e) { return e }
4+var prop = require('../util/prop')
5+var filter = require('./filter')
6+
7+//drop items you have already seen.
8+module.exports = function unique (field, invert) {
9+ field = prop(field) || id
10+ var seen = {}
11+ return filter(function (data) {
12+ var key = field(data)
13+ if(seen[key]) return !!invert //false, by default
14+ else seen[key] = true
15+ return !invert //true by default
16+ })
17+}
18+
util/abort-cb.jsView
@@ -1,0 +1,6 @@
1+module.exports = function abortCb(cb, abort, onAbort) {
2+ cb(abort)
3+ onAbort && onAbort(abort === true ? null: abort)
4+ return
5+}
6+
util/keys.jsView
@@ -1,0 +1,3 @@
1+module.exports = function keys (object) {
2+ return values(Object.keys(object))
3+}
util/prop.jsView
@@ -1,0 +1,9 @@
1+module.exports = function prop (key) {
2+ return key && (
3+ 'string' == typeof key
4+ ? function (data) { return data[key] }
5+ : 'object' === typeof key && 'function' === typeof key.exec //regexp
6+ ? function (data) { var v = key.exec(data); return v && v[0] }
7+ : key
8+ )
9+}
util/tester.jsView
@@ -1,0 +1,11 @@
1+var prop = require('./prop')
2+
3+function id (e) { return e }
4+
5+module.exports = function tester (test) {
6+ return (
7+ 'object' === typeof test && 'function' === typeof test.test //regexp
8+ ? function (data) { return test.test(data) }
9+ : prop (test) || id
10+ )
11+}

Built with git-ssb-web