Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

underarm

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

underarm - npm Package Compare versions

Comparing version
0.4.0
to
0.6.0
+90
lib/array.js
'use strict'
var forEach = require('transduce/array/forEach')
module.exports = function(_r){
// Array Functions
// ---------------
_r.mixin({
forEach: forEach,
each: forEach,
find: find,
detect: find,
every: every,
all: every,
some: some,
any: some,
contains: contains,
include: contains,
findWhere: findWhere,
push: require('transduce/array/push'),
unshift: require('transduce/array/unshift'),
at: at,
slice: require('transduce/array/slice'),
initial: require('transduce/array/initial'),
last: last
})
var iteratee = _r.iteratee,
resolveSingleValue = _r.resolveSingleValue,
_ = _r._
// Return the first value which passes a truth test. Aliased as `detect`.
var _find = require('transduce/array/find')
function find(predicate) {
/*jshint validthis:true*/
resolveSingleValue(this)
return _find(iteratee(predicate))
}
// Determine whether all of the elements match a truth test.
// Aliased as `all`.
var _every = require('transduce/array/every')
function every(predicate) {
/*jshint validthis:true*/
resolveSingleValue(this)
return _every(iteratee(predicate))
}
// Determine if at least one element in the object matches a truth test.
// Aliased as `any`.
var _some = require('transduce/array/some')
function some(predicate) {
/*jshint validthis:true*/
resolveSingleValue(this)
return _some(iteratee(predicate))
}
// Determine if contains a given value (using `===`).
// Aliased as `include`.
function contains(target) {
/*jshint validthis:true*/
return some.call(this, function(x){ return x === target })
}
// Convenience version of a common use case of `find`: getting the first object
// containing specific `key:value` pairs.
function findWhere(attrs) {
/*jshint validthis:true*/
return find.call(this, _.matches(attrs))
}
// Retrieves the value at the given index. Resolves as single value.
var _slice = require('transduce/array/slice')
function at(idx){
/*jshint validthis:true*/
resolveSingleValue(this)
return _slice(idx, idx+1)
}
// Get the last element. Passing **n** will return the last N values.
// Note that no items will be sent until completion.
var _last = require('transduce/array/last')
function last(n) {
if(n === void 0){
/*jshint validthis:true*/
resolveSingleValue(this)
}
return _last(n)
}
}
'use strict'
var util = require('transduce/core/util'),
merge = util.objectMerge,
isArray = util.isArray,
isFunction = util.isFunction
var _r = function(obj, transform) {
if (_r.as(obj)){
if(transform === void 0){
return obj
}
var wrappedFns = obj._wrappedFns.slice()
wrappedFns.push(transform)
var copy = new _r(obj._wrapped, wrappedFns)
copy._opts = merge({}, obj._opts)
return copy
}
if (!(_r.as(this))) return new _r(obj, transform)
if(_r.as(transform)){
this._opts = merge({}, transform._opts)
transform = transform._wrappedFns
} else {
this._opts = {}
}
if(isFunction(transform)){
this._wrappedFns = [transform]
} else if(isArray(transform)){
this._wrappedFns = transform
} else {
this._wrappedFns = []
}
this._wrapped = _r.wrap.call(this, obj)
}
_r.VERSION = '0.6.0'
// Export for browser or Common-JS
// Save the previous value of the `_r` variable.
var previous_r, root
if(typeof window !== 'undefined'){
/*global window*/
var root = window
previous_r = root._r
root._r = _r
_r._ = root._
} else {
root = {}
}
module.exports = _r
// Returns the value if it is a chained transformation, else null
_r.as = function(value){
return value instanceof _r ? value : null
}
// Run Underscore.js in *noConflict* mode, returning the `_` variable to its
// previous owner. Returns a reference to the Underscore object.
_r.noConflict = function() {
root._r = previous_r
return this
}
// Returns a new chained instance using current transformation, but
// wrapping the given source
_r.prototype.withSource = function(obj){
return _r(obj, this)
}
// Add your own custom transducers to the Underscore.transducer object.
_r.mixin = function(obj) {
var name, fn
for(name in obj){
fn = obj[name]
if(typeof fn === 'function'){
_r[name] = fn
_r.prototype[name] = _method(fn)
}
}
}
function _method(func){
return function() {
var method = func.apply(this, arguments)
return _r(this, method)
}
}
'use strict'
var dispatcher = require('redispatch')
module.exports = function(_r){
var _ = _r._,
as = _r.as,
// sentinel to ignore wrapped objects (maintain only last item)
IGNORE = _r.IGNORE = {}
// Transducer Functions
// --------------------
var value = _r.value = dispatcher(),
wrap = _r.wrap = dispatcher(),
unwrap = _r.unwrap = dispatcher(),
empty = _r.empty = dispatcher(),
append = _r.append = dispatcher(),
reduce = _r.reduce = dispatcher(),
_reduce = require('transduce/core/reduce'),
_unreduced = require('transduce/core/unreduced'),
transduce = _r.transduce = dispatcher(),
_transduce = require('transduce/core/transduce'),
into = _r.into = dispatcher(),
transducer = _r.transducer = dispatcher(),
iterator = _r.iterator = dispatcher(),
_iterable = require('transduce/core/iterable'),
_protocols = require('transduce/core/protocols'),
toArray = _r.toArray = dispatcher(),
_toArray = require('transduce/core/into')([]),
_util = require('transduce/core/util'),
iteratee = _r.iteratee = dispatcher()
_r.resolveSingleValue = resolveSingleValue
_r.resolveMultipleValues = resolveMultipleValues
_r.reduced = require('transduce/core/reduced')
_r.isReduced = require('transduce/core/isReduced')
_r.foldl = reduce
_r.inject = reduce
_r.deref = unwrap
_r.conj = append
_r.conjoin = append
_r.dispatch = dispatch
var compose = _r.compose = require('transduce/core/compose')
_r.transformer = require('transduce/core/transformer')
_r.iterable = _iterable
_r.protocols = _protocols
_r.isFunction = _util.isFunction
var isArray = _r.isArray = _util.isArray
var isString = _r.isString = _util.isString
_r.isRegExp = _util.isRegExp
_r.isNumber = _util.isNumber
_r.isUndefined = _util.isUndefined
_r.arrayPush = _util.arrayPush
_r.objectMerge = _util.objectMerge
_r.stringAppend = _util.stringAppend
var identity = _r.identity = _util.identity
// Dispatchers
// -----------
// Resolves the value of the wrapped object, similar to underscore.
// Returns an array, or single value (to match underscore API)
// depending on whether the chained transformation resolves to single value.
value.register(function(self){
if(!self._opts.resolveSingleValue){
return self.into()
}
var ret = self.into(IGNORE)
return ret === IGNORE ? void 0 : ret
})
_r.prototype.value = function(){
return value(this)
}
// Helper to mark transducer to expect single value when
// resolving. Only valid when chaining, but this should be passed
// when called as a function
function resolveSingleValue(self){
_resolveSingleValue(self, true)
}
// Helper to mark transducer to expect multiple values when
// resolving. Only valid when chaining, but this should be passed
// when called as a function.
function resolveMultipleValues(self){
_resolveSingleValue(self, false)
}
function _resolveSingleValue(self, single){
if(as(self)){
self._opts.resolveSingleValue = single
}
}
// Composes and returns the underlying wrapped functions for give chained object
transducer.register(function(self){
var fns = self._wrappedFns
return fns.length ? compose.apply(null, fns) : identity
})
_r.prototype.transducer = _r.prototype.compose = function() {
return transducer(this)
}
reduce.register(function(xf, init, coll) {
if(as(xf)){
xf = transducer(xf)
}
if (coll === null || coll === void 0) coll = empty(coll)
return _reduce(xf, init, coll)
})
// Calls transduce using the chained transformation if function not passed
_r.prototype.reduce = function(init, coll){
if(coll === void 0){
coll = this._wrapped
}
return reduce(this, init, coll)
}
transduce.register(function(xf, f, init, coll){
if(as(xf)){
xf = transducer(xf)
}
return unwrap(_transduce(xf, f, init, coll))
})
// Calls transduce using the chained transformation
_r.prototype.transduce = function(f, init, coll){
if(coll === void 0){
coll = this._wrapped
}
return transduce(this, f, init, coll)
}
// Returns a new coll consisting of to-coll with all of the items of
// from-coll conjoined. A transducer (step function) may be supplied.
into.register(function(to, xf, from){
if(from === void 0){
from = xf
xf = void 0
}
if(from === void 0){
from = empty()
}
if(as(xf)){
xf = transducer(xf)
}
if(to === void 0){
to = empty(from)
}
if(xf === void 0){
return reduce(append, to, from)
}
return transduce(xf, append, to, from)
})
// Calls into using the chained transformation
_r.prototype.into = function(to, from){
if(from === void 0){
from = this._wrapped
}
return into(to, this, from)
}
// Returns a new collection of the empty value of the from collection
toArray.register(function(xf, from){
if(as(xf)){
xf = transducer(xf)
}
if(arguments.length === 1){
return _toArray(xf)
}
return _toArray(xf, from)
})
// calls toArray with chained transformation and optional wrapped object
_r.prototype.toArray = function(from){
if(from === void 0){
from = this._wrapped
}
return toArray(this, from)
}
// Wraps a value used as source for use during chained transformation.
//
// Default returns value, or _r.empty() if undefined.
//
// Dispatch function. To support different types,
// call _r.unwrap.register
wrap.register(function(value){
if(isString(value)){
value = [value]
} else if(value === null || value === void 0){
value = empty()
}
return value
})
// Unwraps (deref) a possibly wrapped value
// Default unwraps values created with _r.reduced,
// or calls value() on chained _r transformations,
// otherwise returns parameter.
//
// Dispatch function. To support different types,
// call _r.unwrap.register
unwrap.register(function(value){
if(as(value)){
return value.value()
}
return _unreduced(value)
})
// Returns an iterator that has next function
// and returns {value, done}. Default looks for
// object with iterator Symbol (or '@@iterator').
// This is available with _r.iterator.Symbol
//
// Dispatch function. To support different types
// call _r.iterator.register and supply function that returns
// an iterator after checking the input using appropriate
// predicates. Return undefined if not supported, so other
// dispatched functions can be checked
iterator.register(function(value){
return _iterable(value)[_protocols.iterator]()
})
// Mostly internal function that generates a callback from the given value.
// For use with generating callbacks for map, filter, find, etc.
//
// Default returns _.iteratee.
//
// Dispatch function. To support different types
// call _r.iteratee.register and supply function that returns
// a callback after checking the input using appropriate
// predicates. Return undefined if not supported, so other
// dispatched functions can be checked
iteratee.register(function(value){
if(as(value)){
return _riteratee(value)
}
return _.iteratee(value)
})
function _riteratee(value){
return function(item){
return value.withSource(item).value()
}
}
// Returns empty object of the same type as argument.
// Default returns [] if isArray or undefined, {} if _.isObject
// and an internal sentinel to ignore otherwise
//
// Dispatch function. To support different types
// call _r.empty.register and supply function that returns
// an empty object after checking the input using appropriate
// predicates. Return undefined if not supported, so other
// dispatched functions can be checked
empty.register(function(obj){
if(obj === void 0 || isArray(obj) || iterator(obj)){
return [] // array if not specified or from array
} else if(_.isObject(obj)){
return {} // object if from object
}
// ignore by default. Default append just maintains last item.
return IGNORE
})
// Appends (conjoins) the item to the collection, and returns collection
//
// Dispatch function. To support different types
// call _r.append.register and supply function that append to the object
// (first param) with the item and optional key after checking the input
// using appropriate predicates.
//
// Return undefined if not supported, so other dispatched functions can be checked
append.register(function(obj, item){
if(isArray(obj)){
obj.push(item)
return obj
}
// just maintain last item
return item
})
// Reducer that dispatches to empty, unwrap and append
function Dispatch(){}
Dispatch.prototype.init = empty
Dispatch.prototype.result = unwrap
Dispatch.prototype.step = append
function dispatch(){
return new Dispatch()
}
}
'use strict'
var symIterator = require('transduce/core/protocols').iterator
module.exports = function(_r){
_r.generate = generate
// Transduces the current chained object by using the chained trasnformation
// and an iterator created with the callback
_r.prototype.generate = function(callback, callToInit){
return this.withSource(generate(callback, callToInit))
}
// Creates an (duck typed) iterator that calls the provided next callback repeatedly
// and uses the return value as the next value of the iterator.
// Marks iterator as done if the next callback returns undefined (returns nothing)
// Can be used to as a source obj to reduce, transduce etc
function generate(callback, callToInit){
var gen = {}
gen[symIterator] = function(){
var next = callToInit ? callback() : callback
return {
next: function(){
var value = next()
return (value === void 0) ? {done: true} : {done: false, value: value}
}
}
}
return gen
}
}
'use strict'
module.exports = function(libs, _r){
var i = 0, len = libs.length, lib
if(_r === void 0){
_r = require('./base')
}
for(; i < len; i++){
lib = libs[i]
// only import if included in build
if(typeof lib === 'function'){
lib(_r)
}
}
return _r
}
'use strict'
var _max = require('transduce/math/max'),
_min = require('transduce/math/min')
module.exports = function(_r){
// Math Functions
// --------------------
_r.mixin({
max: max,
min: min
})
var iteratee = _r.iteratee,
resolveSingleValue = _r.resolveSingleValue
// Return the maximum element (or element-based computation).
function max(f) {
/*jshint validthis:true */
resolveSingleValue(this)
return _max(iteratee(f))
}
// Return the minimum element (or element-based computation).
function min(f) {
/*jshint validthis:true */
resolveSingleValue(this)
return _min(iteratee(f))
}
}
'use strict'
var tap = require('transduce/push/tap'),
_asCallback = require('transduce/push/asCallback'),
_asyncCallback = require('transduce/push/asyncCallback')
module.exports = function(_r){
_r.mixin({tap: tap})
_r.asCallback = asCallback
_r.asyncCallback = asyncCallback
var as = _r.as,
dispatch = _r.dispatch,
transducer = _r.transducer
// Creates a callback that starts a transducer process and accepts
// parameter as a new item in the process. Each item advances the state
// of the transducer. If the transducer exhausts due to early termination,
// all subsequent calls to the callback will no-op and return the computed result.
//
// If the callback is called with no argument, the transducer terminates,
// and all subsequent calls will no-op and return the computed result.
//
// The callback returns undefined until completion. Once completed, the result
// is always returned.
//
// If init is defined, maintains last value and does not buffer results.
// If init is provided, it is dispatched
function asCallback(xf, init){
if(as(xf)){
xf = transducer(xf)
}
var reducer
if(init !== void 0){
reducer = dispatch()
}
return _asCallback(xf, reducer)
}
_r.prototype.asCallback = function(init){
return asCallback(this, init)
}
// Creates an async callback that starts a transducer process and accepts
// parameter cb(err, item) as a new item in the process. The returned callback
// and the optional continuation follow node conventions with fn(err, item).
//
// Each item advances the state of the transducer, if the continuation
// is provided, it will be called on completion or error. An error will terminate
// the transducer and be propagated to the continuation. If the transducer
// exhausts due to early termination, any further call will be a no-op.
//
// If the callback is called with no item, it will terminate the transducer process.
//
// If init is defined, maintains last value and does not buffer results.
// If init is provided, it is dispatched
function asyncCallback(xf, continuation, init){
if(as(xf)){
xf = transducer(xf)
}
var reducer
if(init !== void 0){
reducer = dispatch()
}
return _asyncCallback(xf, continuation, reducer)
}
_r.prototype.asyncCallback = function(continuation, init){
return asyncCallback(this, continuation, init)
}
}
'use strict'
var seq = require('transduce/core/sequence'),
symbol = require('transduce/core/protocols').iterator
module.exports = function(_r){
// Returns a new collection of the empty value of the from collection
_r.sequence = sequence
function sequence(xf, from){
if(_r.as(xf)){
xf = _r.transducer(xf)
}
return seq(xf, from)
}
// calls sequence with chained transformation and optional wrapped object
_r.prototype.sequence = function(from){
if(from === void 0){
from = this._wrapped
}
return sequence(this, from)
}
_r.prototype[symbol] = function(){
return _r.iterator(this.sequence())
}
}
'use strict'
module.exports = function(_r){
// String Functions
// --------------------
_r.mixin({
split: require('transduce/string/split'),
join: join,
nonEmpty: require('transduce/string/nonEmpty'),
lines: require('transduce/string/lines'),
chars: require('transduce/string/chars'),
words: require('transduce/string/words')
})
var _join = require('transduce/string/join')
function join(separator){
/*jshint validthis:true */
_r.resolveSingleValue(this)
return _join(separator)
}
}
'use strict'
var slice = Array.prototype.slice
module.exports = function(_r){
// Base Transducers
// ----------------
_r.mixin({
map: map,
collect: map,
filter: filter,
select: filter,
remove: remove,
reject: remove,
take: take,
first: take,
head: take,
takeWhile: takeWhile,
drop: drop,
rest: drop,
tail: drop,
dropWhile: dropWhile,
cat: cat,
mapcat: mapcat,
partitionAll: partitionAll,
chunkAll: partitionAll,
partitionBy: partitionBy,
compact: compact,
invoke: invoke,
pluck: pluck,
where: where
})
var iteratee = _r.iteratee,
_ = _r._,
util = require('transduce/core/util'),
isFunction = util.isFunction,
identity = util.identity
// Return the results of applying the iteratee to each element.
var _map = require('transduce/transducers/map')
function map(f) {
return _map(iteratee(f))
}
// Return all the elements that pass a truth test.
// Aliased as `select`.
var _filter = require('transduce/transducers/filter')
function filter(predicate) {
return _filter(iteratee(predicate))
}
// Return all the elements for which a truth test fails.
var _remove = require('transduce/transducers/remove')
function remove(predicate) {
return _remove(iteratee(predicate))
}
// Get the first element of an array. Passing **n** will return the first N
// values in the array. Aliased as `head` and `take`.
var _take = require('transduce/transducers/take')
function take(n) {
if(n === void 0){
/*jshint validthis:true*/
_r.resolveSingleValue(this)
n = 1
} else {
n = (n > 0) ? n : 0
}
return _take(n)
}
// takes items until predicate returns false
var _takeWhile = require('transduce/transducers/takeWhile')
function takeWhile(predicate) {
return _takeWhile(iteratee(predicate))
}
// Returns everything but the first entry. Aliased as `tail` and `drop`.
// Passing an **n** will return the rest N values.
var _drop = require('transduce/transducers/drop')
function drop(n) {
n = (n === void 0) ? 1 : (n > 0) ? n : 0
return _drop(n)
}
// Drops items while the predicate returns true
var _dropWhile = require('transduce/transducers/dropWhile')
function dropWhile(predicate) {
return _dropWhile(iteratee(predicate))
}
// Concatenating transducer.
// NOTE: unlike libraries, cat should be called as a function to use.
// _r.cat() not _r.cat
var _cat = require('transduce/transducers/cat')
function cat(){
return _cat
}
// mapcat.
// Composition of _r.map(f) and _r.cat()
var _mapcat = require('transduce/transducers/mapcat')
function mapcat(f){
return _mapcat(iteratee(f))
}
// Partitions the source into arrays of size n
// When transformer completes, the array will be stepped with any remaining items.
// Alias chunkAll
var _partitionAll = require('transduce/transducers/partitionAll')
function partitionAll(n){
return _partitionAll(n)
}
// Partitions the source into sub arrays while the value of the function
// changes equality.
var _partitionBy = require('transduce/transducers/partitionBy')
function partitionBy(f){
return _partitionBy(iteratee(f))
}
// Trim out all falsy values from an array.
function compact() {
return filter(identity)
}
// Invoke a method (with arguments) on every item in a collection.
function invoke(method) {
var args = slice.call(arguments, 2),
isFunc = isFunction(method)
return map(function(value) {
return (isFunc ? method : value[method]).apply(value, args)
})
}
// Convenience version of a common use case of `map`: fetching a property.
function pluck(key) {
return map(_.property(key))
}
// Convenience version of a common use case of `filter`: selecting only objects
// containing specific `key:value` pairs.
function where(attrs) {
return filter(_.matches(attrs))
}
}
'use strict'
var _unique = require('transduce/transducers/unique'),
_dedupe = require('transduce/transducers/dedupe')
module.exports = function(_r){
// Array Functions
// ---------------
_r.mixin({
unique: unique,
uniq: unique
})
var _ = _r._,
iteratee = _r.iteratee
// Produce a duplicate-free version of the array. If the array has already
// been sorted, you have the option of using a faster algorithm.
// Aliased as `unique`.
function unique(isSorted, f) {
if (isSorted !== true && isSorted !== false) {
f = isSorted
isSorted = false
}
if(isSorted){
return _dedupe()
}
if (f !== void 0) f = iteratee(f)
return _unique(f)
}
}
'use strict'
module.exports = function(_r){
var _ = _r._ || {}
_r._ = _
_.debounce = require('lodash-node/compat/function/debounce')
_.throttle = require('lodash-node/compat/function/throttle')
}
'use strict'
// Based on Underscore.js 1.7.0
// http://underscorejs.org
//
// Which is distributed under MIT License:
// Underscore.js > (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// Underscore.js > Underscore may be freely distributed under the MIT license.
var util = require('transduce/core/util'),
isFunction = util.isFunction,
isArray = util.isArray,
isString = util.isString,
isNumber = util.isNumber,
identity = util.identity
module.exports = function(_r){
var _ = _r._ || {}
_r._ = _
_.iteratee = iteratee
_.matches = matches
_.property = property
}
function iteratee(value){
var f
if(isNull(value)){
f = identity
} else if(isFunction(value)){
f = value
} else if(isKey(value)){
f = property(value)
} else {
f = matches(value)
}
return f
}
function property(key){
return function(value){
return value[key]
}
}
function matches(attrs){
var ps = pairs(attrs),
len = ps.length
return function(value){
if(isNull(value)){
return len === 0
}
var i = 0, p, k, v
for(; i < len; i++){
p = ps[i]
k = p[0]
v = p[1]
if(v !== value[k] || !(k in value)){
return false
}
}
return true
}
}
function isNull(value){
return value === void 0 || value === null
}
function isKey(value){
return isString(value) || isNumber(value)
}
function pairs(value){
var key, ps = []
for(key in value){
if(value.hasOwnProperty(key)){
ps.push([key, value[key]])
}
}
return ps
}
+3
-5
{
"name": "underarm",
"main": "build/underarm.min.js",
"version": "0.2.1",
"version": "0.6.0",
"homepage": "https://github.com/kevinbeaty/underarm",

@@ -9,3 +9,3 @@ "authors": [

],
"description": "Async Reactive Transducers for JavaScript with Underscore API",
"description": "Transducers for JavaScript with Underscore API and Async extensions",
"moduleType": [

@@ -28,6 +28,4 @@ "amd",

"bower_components",
"test",
"tests",
"*-old"
"test"
]
}

@@ -1,2 +0,2 @@

Copyright (C) 2012-2014 Kevin Beaty
Copyright (C) 2012-2015 Kevin Beaty

@@ -3,0 +3,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy

{
"name": "underarm",
"version": "0.4.0",
"description": "Underscore Transducer meets Reactive Programming",
"version": "0.6.0",
"description": "Transducers for JavaScript with Underscore API and Async extensions",
"main": "underarm.js",

@@ -16,15 +16,18 @@ "homepage": "https://github.com/kevinbeaty/underarm",

"underscore",
"transducer",
"reducer",
"reactive",
"rx",
"transducer",
"reducer"
"transduce"
],
"author": "Kevin Beaty",
"license": "MIT",
"bugs": {
"url": "https://github.com/kevinbeaty/underarm/issues"
},
"dependencies": {
"underscore-transducer": "~0.5.0",
"transduce": "~0.6.0",
"redispatch": "0.0.2",
"transduce-async": "~0.3.0",
"any-promise": "~0.1.0",
"lodash-node": "~3.3.0",
"transduce": "~0.6.0"
"lodash-node": "~3.3.0"
},

@@ -31,0 +34,0 @@ "devDependencies": {

+577
-17
# Underarm
[![Build Status](https://secure.travis-ci.org/kevinbeaty/underarm.png)](http://travis-ci.org/kevinbeaty/underarm)
Use JavaScript with the familiar [Underscore.js][1] API with extra goodies like and [asynchronous (reactive) execution][2] and [lazy generators and callback processes][4].
Use JavaScript transducers with the familiar [Underscore.js][1] API with extra goodies like [lazy generators and callback processes][4].
Works with [any-promise][6] library (a pollyfill, es6-promise, promise, native-promise-only, bluebird, rsvp, when, q ... your choice) for asynchronous execution.
If you are not familiar with transducers, check out [Transducers Explained][3].
Underarm is an extension to [underscore-transducer][5]. All methods there work with Underarm as well. Underarm allows any transducer to become asynchronous: Promises can be used and returned in `init`, `step` and `result`. If the transformation is not marked `async` behaves exactly the same as underscore-transducer.
Too much API for you? Just grab what you need from the [transduce][14] libraries, which underarm is based.
## Install
Works with [any-promise][8] library (a pollyfill, es6-promise, promise, native-promise-only, bluebird, rsvp, when, q ... your choice) for asynchronous execution. Underarm allows any transducer to become asynchronous: Promises can be used and returned in `init`, `step` and `result`.
Install your Promise library preference before underarm and it will be auto detected and used.
```bash
$ npm install promise # or es6-promise, bluebird, q, when, rsvp ... see any-promise
$ npm install underarm
$ bower install underarm
```
### Browser

@@ -22,10 +27,313 @@ Include an ES6 Promise Pollyfill. Then include the browser version of underarm.

### Node.js
Library uses [any-promise][6] to allow choice of Promise library.
Structured to allow creation of custom builds by loading only desired libs. For example, see:
```bash
$ npm install promise # or es6-promise, bluebird, q, when, rsvp ... see any-promise
$ npm install underarm
* [Base Development][20]
* [Base Minified][21]
Created by using `browserify` with [this loader][22].
### Transducers
First some helper functions and imports.
```javascript
// import, mixin and helper functions
var _r = require('underarm');
function isEven(x){
return x % 2 !== 1;
}
function inc(x){
return x+1;
}
// prints every result and input. Useful with tap
function printIt(result, input){
console.log(input+' ['+result+']');
}
var trans, result;
```
Chaining transducers is the same as function composition. Composed transducers are executed left to right.
```javascript
result = _r.into([], _r.compose(_r.filter(isEven), _r.map(inc)), [1,2,3,4]);
// [ 3, 5 ]
// these are also the same
trans = _r().filter(isEven).map(inc).value();
result = _r.into([], trans, [1,2,3,4, 5]);
result = _r().filter(isEven).map(inc).toArray([1,2,3,4,5]);
// [ 3, 5 ]
```
Like underscore, use `tap` to intercept intermediate results. Accepts current result and item just like the step function. The return value is ignored.
```javascript
result = _r()
.filter(function(num) { return num % 2 == 0; })
.tap(printIt)
.map(function(num) { return num * num })
.toArray([1,2,3,200]);
// 2 []
// 200 [4]
// [4, 40000 ]
```
Support for underscore collection functions.
```javascript
result = _r().invoke('sort').toArray([[5, 1, 7], [3, 2, 1]]);
// [ [ 1, 5, 7 ], [ 1, 2, 3 ] ]
var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 40}];
result = _r.into([], _r.pluck('name'), stooges);
// ['moe', 'larry', 'curly' ]
result = _r.into([], _r.where({age: 40}), stooges);
// [ { name: 'moe', age: 40 }, { name: 'curly', age: 40 } ]
result = _r.into([], _r.findWhere({age: 40}), stooges);
// [ { name: 'moe', age: 40 } ]
result = _r.into([], _r.every(isEven), [0, 2, 8, 4, 8]);
// [true]
result = _r.into([], _r.some(isEven), [1, 3, 7, 11, 9]);
// [false]
result = _r.into([], _r.contains(3), [1, 3, 7, 11, 9]);
// [true]
result = _r.into([], _r.find(isEven), [7, 8, 7, 11, 12]);
// [8]
result = _r.into([], _r.first(3), [1, 9, 13, 11, 9]);
// [1, 9, 13 ]
```
Transducers implemented
#### Base
Base Transducers mixing common functionality from supported [transduce][14] implementations.
##### map(f)
Step all items after applying a mapping function to each item. Wraps mapping function with `_r.iteratee`.
Alias: collect
##### filter(predicate)
Step all the items that pass a truth test. Wraps predicate with `_r.iteratee`.
Alias: select.
##### remove(predicate)
Step all the items that fail a truth test. Wraps predicate with `_r.iteratee`.
Alias: reject
##### take(n?)
Step the first item if `n` is undefined. Passing `n` will step the first N values in the array.
Resolves as single value if n is undefined.
Alias: first, head
##### takeWhile(predicate)
Takes items until predicate returns false. Wraps predicate with `_r.iteratee`.
##### drop(n?)
Steps everything but the first item if n is undefined. Passing an `n` will drop N values.
Alias: rest, tail
##### dropWhile(predicate)
Drops items while predicate returns true. Wraps predicate with `_r.iteratee`.
##### cat
Concatenating transducer.
NOTE: unlike libraries, cat should be called as a function. Use `_r.cat()` instead of `_r.cat`
##### mapcat(f)
Composition of `_r.map(f)` and `_r.cat()`. Wraps mapping function with `_r.iteratee`
##### partitionAll(n)
Partitions the source into arrays of size n. When transformer completes, the array will be stepped with any remaining items.
Alias: chunkAll
##### partitionBy(f)
Partitions the source into sub arrays while the value of the function changes equality. Wrap partitioning function by `_r.iteratee`.
##### compact()
Trim out all falsey values.
##### invoke(method)
Invoke a method (with arguments) on every item.
##### pluck(key)
Convenience version of a common use case of `map`: fetching a property.
##### where(attrs)
Convenience version of a common use case of `filter`: selecting only objects containing specific `key:value` pairs.
#### Array
##### forEach(iteratee)
Passes every item through unchanged, but after executing `callback(item, idx)`. Can be useful for "tapping into" composed transducer pipelines. The return value of the callback is ignored, item is passed unchanged. (See [transduce-stream][7] for a use case.)
Alias: each
##### find(predicate)
Like filter, but terminates transducer pipeline with the result of the first item that passes the predicate test. Will always step either 0 (if not found) or 1 (if found) values.
Resolves as single value.
Alias: detect
##### findWhere(attrs)
Convenience version of a common use case of `find`: getting the first object containing specific `key:value` pairs. Early termination when found.
Resolves as single value.
##### every(predicate?)
Checks to see if every item passes the predicate test. Steps a single item `true` or `false`. Early termination on `false`. Wraps predicate in `_r.iteratee`
Resolves as single value.
Alias: all
##### some(predicate?)
Checks to see if some item passes the predicate test. Steps a single item `true` or `false`. Early termination on `true`. Wraps predicate in `_r.iteratee`
Resolves as single value.
Alias: any
##### contains(target)
Does the stream contain the target value (`target === item`)? Steps a single item `true` or `false`. Early termination on `true`.
Resolves as single value.
Alias: include
##### push(...args)
Passes all items straight through until the result is requested. Once completed, steps every argument through the pipeline, before returning the result. This effectively pushes values on the end of the stream.
##### unshift(...args)
Before stepping the first item, steps all arguments through the pipeline, then passes every item through unchanged. This effectively unshifts values onto the beginning of the stream.
##### at(index)
Retrieves the value at the given index. Similar to indexing into an array.
Resolves as single value.
##### slice(begin? end?)
Like array slice, but with transducers. Steps items between `begin` (inclusive) and `end` (exclusive). If either index is negative, indexes from end of transformation. If `end` is undefined, steps until result of transformation. If `begin` is undefined, begins at 0.
Note that if either index is negative, items will be buffered until completion.
##### initial(n?)
Steps everything but the last entry. Passing `n` will step all values excluding the last N.
Note that no items will be sent and all items will be buffered until completion.
##### last(n?)
Step the last element. Passing `n` will step the last N values.
Resolves as single value if `n` is undefined
Note that no items will be sent until completion.
##### unique(isSorted?, iteratee?)
Produce a duplicate-free version of the transformation. If the transformation has already been sorted, you have the option of using an algorithm that maintains less state. If iteratee is passed, it will be wrapped with `_r.iteratee` and use return value for comparison.
Alias: uniq
#### Math
##### min(f?)
Steps the max value on the result of the transformation. if `f` is provided, it is wrapped with `_r.iteratee` and called with each item and the return value is used to compare values. Otherwise, the items are compared as numbers.
Resolves as single value.
##### max(f?)
Steps the max value on the result of the transformation. if `f` is provided, it is wrapped with `_r.iteratee` and called with each item and the return value is used to compare values. Otherwise, the items are compared as numbers.
Resolves as single value.
#### Strings
Strings are a sequence of characters, so you can transduce over those as well. Particularly useful with [transduce-stream][7].
Functions that `split` over streams are treated as a substring, and splits across the entire transformation. This allows methods to work with chunks sent through streams. Methods that `split` over the String are processed lazily and as soon as possible: `lines`, `words` and `chars` will process a line/word/char as they are received, and buffer any intermediate chunks appropriately.
##### split(separator, limit)
Works like `''.split` but splits across entire sequence of items. Accepts separator (String or RegExp) and limit of substrings to send.
##### join(separator)
Buffers all items and joins results on transducer `result`.
Resolves as a single value.
##### nonEmpty()
Only steps items that are non empty strings (`input.trim().length > 0`).
##### lines(limit?)
Split chunks into lines and steps each line up to the optional limit.
##### chars(limit?)
Split chunks into characters and steps each char up to the optional limit.
##### words(delimiter?, limit?)
Split chunks into words and steps each word up to the optional limit. Can pass an optional delimiter to identify words, default on whitespace (`/\s+/`).
### Chaining
Chaining is implicit when calling as a function `_r()`, and the source can be optionally passed as an argument to the function. When chaining, each of the transducers can be called as a builder similar to underscore.
##### value()
Call on a chained transformation to sequence a wrapped value through the transformation and resolve as a value. The value returned is similar to underscore. Transducers that resolve as a single value are noted above. If a function does not resolve as a single value, resolves a a collection determined by `_r.empty(source)` (see below, normally an array).
##### compose()
Call on chained transformation to compose all transducer functions in chain and return a transducer that can be used to pass to transduce functions.
Alias: transducer
##### mixin()
Mixin custom transducer creating functions. Transducer creating functions will be called with arguments passed when chaining and should return a transducer. All transducers described above are mixed in.
### Transduce functions
Adds functionality from [transduce][14] with default values from dispatched functions and chained transformations.
##### toArray(xf?, from?)
Returns a new orray by iterating through`from` after running it through the optional transformation.
If called on a chained transformation, uses the composed transformation as `xf`. If `from` is not defined, uses the wrapped source when creating the chain, `_r(wrapped)`.
##### into(to?, xf?, from?)
Returns a new collection appending all items into the empty collection `to` by passing all items from source collection `from` through the transformation `xf`.
Uses generic dispatch `_r.append` for reducing function. If the `from` collection is undefined, creates an empty collection using `_r.empty()`. If `xf` is a chained transformation, composes it.
Delegates to `_r.transduce(xf, _r.append, to, from)` if `xf is defined, otherwise `_r.reduce(_r.append, to, from)` if `xf` is undefined.
If called on a chained transformation, uses the composed transformation as `xf`. If `from` is not defined, uses the wrapped source when creating the chain, `_r(wrapped)`. If `to` is not defined, uses `_r.empty(from)` to create an empty value.
##### transduce(xf?, f, init, coll?)
Transduce over a transformation using the installed transducers library, using chained transformation if chaining. If chaining and the source collection is not defined, uses wrapped source passed when creating the chain `_r(wrapped)`. Calls generic dispatch `_r.unwrap` with result before returning.
##### reduce(f, init, coll?)
Reduces over a transformation using the installed transducers library. If the source `coll` is undefined, or null, creates an empty source by dispatching to `_r.empty(coll)`.
Alias: foldl, inject
##### reduced
Ensures values are reduced to signal early termination when stepping through a transformation. Probably only useful if you want to mixin custom transducers. Use `_r.isReduced` to check if a value is wrapped as `reduced`. Use generic dispatch `_r.unwrap` to unwrap reduced values.
### Async

@@ -38,3 +346,3 @@ Uses [transduce-async][15] to support promises in transducer `init`, `step` and `result`.

##### prototype.value()
Resolve value as [underscore-transducer][5] if not `async`. If chained transformation is `async` returns a promise for the value of the transformation
If chained transformation is `async` returns a promise for the value of the transformation

@@ -48,3 +356,3 @@ ##### prototype.then(resolve, reject)

#### transduce(xf?, f, init, coll?)
Like a normal transduce when chained transformation is `async`. If `async`, `init` and `coll` can be a Promise and `xf` can be an async transducer. The value of `coll` can be anything that can be converted to an iterator using [transduce-protocol][16]. The return value is a Promise for the result of the transformation.
Like a normal transduce when chained transformation is `async`. If `async`, `init` and `coll` can be a Promise and `xf` can be an async transducer. The value of `coll` can be anything that can be converted to an iterator using [transduce][14]. The return value is a Promise for the result of the transformation.

@@ -71,11 +379,260 @@ ##### into(to?, xf?, from?)

### License
### Iterators
Transduce, into, etc. accept generators or any iterator in addition to arrays. An iterator can either adapt the protocol or simply define a next function.
```javascript
function* genNums(){
yield 1;
yield 2;
yield 3;
yield 4;
}
result = _r.into([], _r.first(3), genNums());
// [1, 2, 3 ]
```
### Sequence generation
Generate will create an iterator that executes a callback. This can be used to generate potentially infinite sequences.
```javascript
// Returns a function that generates the next fibonacci number
// every time it is called. Use with generators below
function fib(){
var x=1, y=1;
return function(){
var prev = x;
x = y;
y += prev;
return prev;
}
}
```
If not chaining, creates an iterator that can be used with transduce. If chaining, creates an iterator a wraps the result. Pass true as second argument optionally call function to init on each iteration (allows reuse).
```javascript
// call on init to allow reuse
trans = _r().generate(fib, true).first(7);
result = trans.value();
result = trans.value();
```
### Callback Processes
Transducers can be consumed by reduce, but since they are designed to be independent, we can use them in a variety of contexts that consume an input and produce a result, such as [CSP][3]. We can also create a process using a callback where each call advances a step in the process. These can be used as event handlers (like the [demo][4]).
```javascript
var $demo = $('#demo3'),
coords = _r()
.where({type:'mousemove'})
.map(function(e){return {x: e.clientX, y: e.clientY}})
.map(function(p){return '('+p.x+', '+p.y+')'})
.each(updateText)
.asCallback(),
click = _r()
.where({type:'click'})
.each(updateCount)
.asCallback(),
events = _r()
.each(coords)
.each(click)
.asCallback();
$demo.on('mousemove click', events);
function updateText(p){
$demo.html(p);
}
function updateCount(e, idx){
$demo.html('Click '+idx);
}
```
We are composing transducers. The previous examples are all using transducers behind the scenes. Method chaining is implicit and is composition, `_r.generate` uses an iterator and passes on to `transduce`. Even `asCallback` uses transducers but steps through the results using the argument of a callback, instead of reducing over the results.
##### tap(interceptor)
Transduce also adds `tap`, which invokes interceptor with each result and item, and then steps through unchanged. The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain. Executes interceptor with current result and item.
### Node Async
If you are using Node.js, `asyncCallback` returns a callback that follows the standard convention of `fn(err, item)` and accepts a continuation that is called on completion or error.
### Streams
You can transduce over Node.js Streams with [transduce-stream][7].
```javascript
// test.js
var _r = require('underarm');
stream = require('transduce-stream');
var transducer = _r()
.words()
.map(function(x){return (+x * +x)+ ' '})
.uniq()
.take(4)
.push('\n')
.compose();
process.stdin.resume();
process.stdin.pipe(stream(transducer)).pipe(process.stdout);
```
Run this from the terminal to calculate a formatted sequence of the first 4 unique squared values.
```bash
$ echo '33 27 33 444' | node test.js
1089 729 197136
$ node test.js << EOT
12 32
33 33
33 43
12 33 12
EOT
144 1024 1089 1849
```
### Generic dispatch
Since input and output are separated the transducer transformation, transducers can be reduced, and sequences can be created over any object that supports the following methods.
##### iterator(value)
Returns an iterator that has next function and returns `{value, done}`. Default looks for object with iterator Symbol (or `'@@iterator'`)
##### iteratee(value)
Just like underscore, you can use "where style" objects and strings with functions that expect a mapping function or a predicate. By default, uses `_.iteratee` to match this behavior, but setup as a dispatched function to allow custom behavior.
##### empty(value?)
Returns empty object of the same type as argument. Default returns `[]` if `_.isArray` or `undefined`, `{}` if `_.isObject` and an internal sentinel to ignore otherwise (used when not buffering in `asCallback` or chained `value` expects single value.
##### append(result, item)
Accepts an item and optional key and appends the item to the object. By default, appends to arrays and objects by key and returns last item when used in `asCallback` or chained transducer with single `value`.
##### wrap(value?) / unwrap(value)
When chaining transducers, the object passed to `_r(obj)` is dispatched to `_r.wrap`. By default, the object is not wrapped if it is defined, and wrapped with `_r.empty()` if not defined. When transducing over the sequence (with `value`, `into`, etc.) the object is then unwrapped with `_r.unwrap`. By default, unwrap calls `_r().value()` on chained transformations, extracts value from `_r.reduced` or simply returns the value. You can provide custom dispatchers for custom wrapped values.
#### Example
You can dispatch to custom objects by registering supporting dispatch functions. Say, for example, you love using [immutable][6] collections.
```javascript
var _r = require('underarm'),
_ = require('underscore'),
Immutable = require('immutable'),
Vector = Immutable.Vector;
_r.iterator.register(function(obj){
if(obj instanceof Vector){
return obj.values();
}
});
_r.empty.register(function(obj){
if(obj instanceof Vector){
return Vector.empty();
}
});
_r.append.register(function(obj, item){
if(obj instanceof Vector){
return obj.push(item);
}
});
function mult(x){
return function(y){
return x * y;
}
}
function isEven(x){
return !(x % 2);
}
var vector = Vector(1,2,3,4);
// Vector [ 1, 2, 3, 4 ]
_r.sequence(vector);
// Vector [ 3, 6, 9, 12 ]
_r.sequence(_r.map(mult(3)), vector);
// Vector [ 7, 14, 21, 28 ]
_r(vector).map(mult(7)).sequence();
// Vector [ 14, 28 ]
_r(vector).map(mult(7)).filter(isEven).sequence();
// Vector [ 1, 2, 3, 4 ]
_r(vector).sequence();
```
By default, `value` transduces into an empty array if multiple values are expected, and a single value if single value is expected to match the Underscore API. To override the behavior of multiple values, simply register a dispatch an empty for an undefined object (`value` calls `_r.empty()` which by default returns an array).
```javascript
// [ 1, 2, 3, 4 ]
_r(vector).value();
_r.empty.register(function(obj){
if(_.isUndefined(obj)){
return Vector.empty();
}
});
// Vector [ 1, 2, 3, 4 ]
_r(vector).value();
```
#### Utils
Finally, adds utils from [transduce][14].
##### compose()
Simple function composition of arguments. Useful for composing (combining) transducers.
##### iterable(value)
Returns the iterable for the parameter. Returns value if conforms to iterable protocol. Returns `undefined` if cannot return en iterable.
The return value will either conform to iterator protocol that can be invoked for iteration or will be undefined.
Supports anything that returns true for `isIterable` and converts arrays to iterables over each indexed item. Converts to functions to infinite iterables that always call function on next
##### transformer(value)
Attempts to convert the parameter into a transformer. If cannot be converted, returns `undefined`. If defined, the return value will have `init`, `step`, `result` methods that can be used for transformation. Converts arrays (`arrayPush`), strings (`stringAppend`), objects (`objectMerge`), functions (wrap as reducing function) or anything that `isTransformer` into a transformer.
##### protocols
Symbols (or strings that act as symbols) for `@@iterator` and [`@@transformer`][10] that you can use to configure your custom objects.
##### identity(value)
Always returns value
##### arrayPush(arr, item)
Array.push as a reducing function. Calls push and returns array;
##### objectMerge(object, item)
Merges the item into the object. If `item` is an array of length 2, uses first (0 index) as the key and the second (1 index) as the value. Otherwise iterates over own properties of items and merges values with same keys into the result object.
##### stringAppend(string, item)
Appends item onto result using `+`.
##### is{Array, String, RegExp, Number, Undefined}
Predicates for object types
#### License
MIT
[1]: http://underscorejs.org/
[2]: http://simplectic.com/projects/underarm/
[3]: http://simplectic.com/blog/2014/transducers-explained-1/
[4]: http://simplectic.com/projects/underscore-transducer/
[5]: https://github.com/kevinbeaty/underscore-transducer
[6]: https://github.com/kevinbeaty/any-promise
[4]: http://simplectic.com/projects/underarm/
[5]: http://clojure.org/transducers
[6]: https://github.com/facebook/immutable-js
[7]: https://github.com/transduce/transduce-stream
[8]: https://github.com/kevinbeaty/any-promise
[12]: https://raw.githubusercontent.com/kevinbeaty/underarm/master/build/underarm.js

@@ -85,2 +642,5 @@ [13]: https://raw.githubusercontent.com/kevinbeaty/underarm/master/build/underarm.min.js

[15]: https://github.com/transduce/transduce-async
[16]: https://github.com/transduce/transduce-protocol
[18]: https://github.com/kevinbeaty/underarm
[20]: https://raw.githubusercontent.com/kevinbeaty/underarm/master/build/underarm.base.js
[21]: https://raw.githubusercontent.com/kevinbeaty/underarm/master/build/underarm.base.min.js
[22]: https://github.com/kevinbeaty/underarm/tree/master/underarm.base.js

@@ -1,3 +0,4 @@

module.exports = require('underscore-transducer/lib/load')([
require('./lib/async')],
require('underscore-transducer/underscore-transducer.base'))
module.exports = require('./lib/load')([
require('./lib/util'),
require('./lib/dispatch'),
require('./lib/transduce')])

@@ -1,5 +0,14 @@

module.exports = require('underscore-transducer/lib/load')([
require('./lib/lodash'),
module.exports = require('./lib/load')([
require('./lib/util'),
require('./lib/util-async'),
require('./lib/dispatch'),
require('./lib/transduce'),
require('./lib/sequence'),
require('./lib/array'),
require('./lib/unique'),
require('./lib/push'),
require('./lib/iterator'),
require('./lib/math'),
require('./lib/string'),
require('./lib/async'),
require('./lib/sample')],
require('underscore-transducer'))
require('./lib/sample')])
'use strict'
module.exports = function(_r){
var _ = _r._ || {}
_.debounce = require('lodash-node/compat/function/debounce')
_.throttle = require('lodash-node/compat/function/throttle')
}

Sorry, the diff of this file is not supported yet