You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
2.0 KiB
100 lines
2.0 KiB
5 years ago
|
var looper = require('looper')
|
||
|
|
||
|
var window = module.exports = function (init, start) {
|
||
|
return function (read) {
|
||
|
start = start || function (start, data) {
|
||
|
return {start: start, data: data}
|
||
|
}
|
||
|
var windows = [], output = [], ended = null
|
||
|
var data, end
|
||
|
var j = 0
|
||
|
|
||
|
return function (abort, cb) {
|
||
|
if(output.length)
|
||
|
return cb(null, output.shift())
|
||
|
if(ended)
|
||
|
return cb(ended)
|
||
|
var i = 0
|
||
|
var k = j ++
|
||
|
read(abort, looper(function (end, data) {
|
||
|
var next = this
|
||
|
var reduce, update, once = false
|
||
|
if(end)
|
||
|
ended = end
|
||
|
|
||
|
function _update (end, _data) {
|
||
|
if(once) return
|
||
|
once = true
|
||
|
delete windows[windows.indexOf(update)]
|
||
|
output.push(start(data, _data))
|
||
|
}
|
||
|
|
||
|
if(!ended)
|
||
|
update = init(data, _update)
|
||
|
|
||
|
if(update)
|
||
|
windows.push(update)
|
||
|
else
|
||
|
//don't allow data unless a window started here!
|
||
|
once = true
|
||
|
|
||
|
windows.forEach(function (update, i) {
|
||
|
update(end, data)
|
||
|
})
|
||
|
|
||
|
if(output.length)
|
||
|
return cb(null, output.shift())
|
||
|
else if(ended)
|
||
|
return cb(ended)
|
||
|
else
|
||
|
read(null, next)
|
||
|
|
||
|
}))
|
||
|
}
|
||
|
}}
|
||
|
|
||
|
window.recent = function (size, time) {
|
||
|
var current = null
|
||
|
return window(function (data, cb) {
|
||
|
if(current) return
|
||
|
current = []
|
||
|
var timer
|
||
|
|
||
|
function done () {
|
||
|
var _current = current
|
||
|
current = null
|
||
|
clearTimeout(timer)
|
||
|
cb(null, _current)
|
||
|
}
|
||
|
|
||
|
if(time)
|
||
|
timer = setTimeout(done, time)
|
||
|
|
||
|
return function (end, data) {
|
||
|
if(end) return done()
|
||
|
current.push(data)
|
||
|
if(size != null && current.length >= size)
|
||
|
done()
|
||
|
}
|
||
|
}, function (_, data) {
|
||
|
return data
|
||
|
})
|
||
|
}
|
||
|
|
||
|
window.sliding = function (reduce, width) {
|
||
|
width = width || 10
|
||
|
var k = 0
|
||
|
return window(function (data, cb) {
|
||
|
var acc
|
||
|
var i = 0
|
||
|
var l = k++
|
||
|
return function (end, data) {
|
||
|
if(end) return
|
||
|
acc = reduce(acc, data)
|
||
|
if(width <= ++ i)
|
||
|
cb(null, acc)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
|