var keys = exports.keys = function (object) { return values(Object.keys(object)) } function abortCb(cb, abort, onAbort) { cb(abort) onAbort && onAbort(abort === true ? null: abort) return } var once = exports.once = function (value, onAbort) { return function (abort, cb) { if(abort) return abortCb(cb, abort, onAbort) if(value != null) { var _value = value; value = null cb(null, _value) } else cb(true) } } var values = exports.values = exports.readArray = function (array, onAbort) { if(!array) return function (abort, cb) { if(abort) return abortCb(cb, abort, onAbort) return cb(true) } if(!Array.isArray(array)) array = Object.keys(array).map(function (k) { return array[k] }) var i = 0 return function (abort, cb) { if(abort) return abortCb(cb, abort, onAbort) cb(i >= array.length || null, array[i++]) } } var count = exports.count = function (max) { var i = 0; max = max || Infinity return function (end, cb) { if(end) return cb && cb(end) if(i > max) return cb(true) cb(null, i++) } } var infinite = exports.infinite = function (generate) { generate = generate || Math.random return function (end, cb) { if(end) return cb && cb(end) return cb(null, generate()) } } //a stream that ends immediately. var empty = exports.empty = function () { return function (abort, cb) { cb(true) } } //a stream that errors immediately. var error = exports.error = function (err) { return function (abort, cb) { cb(err) } }