Comparing version 0.1.17 to 0.2.0
218
flyd.js
@@ -1,2 +0,2 @@ | ||
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.flyd=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | ||
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.flyd = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | ||
var curryN = require('ramda/src/curryN'); | ||
@@ -19,3 +19,3 @@ | ||
function on(f, s) { | ||
stream([s], function() { f(s.val); }); | ||
return stream([s], function() { f(s.val); }); | ||
} | ||
@@ -65,3 +65,4 @@ | ||
inStream = s; | ||
var returnVal = s.fn(s, s.depsChanged); | ||
s.fnArgs[1] = s.depsChanged; | ||
var returnVal = s.fn.apply(s.fn, s.fnArgs); | ||
if (returnVal !== undefined) { | ||
@@ -196,2 +197,3 @@ s(returnVal); | ||
s.shouldUpdate = false; | ||
s.fnArgs = [s, s.depsChanged].concat(s.deps); | ||
addListeners(deps, s); | ||
@@ -293,84 +295,10 @@ return s; | ||
},{"ramda/src/curryN":4}],2:[function(require,module,exports){ | ||
/** | ||
* A special placeholder value used to specify "gaps" within curried functions, | ||
* allowing partial application of any combination of arguments, | ||
* regardless of their positions. | ||
* | ||
* If `g` is a curried ternary function and `_` is `R.__`, the following are equivalent: | ||
* | ||
* - `g(1, 2, 3)` | ||
* - `g(_, 2, 3)(1)` | ||
* - `g(_, _, 3)(1)(2)` | ||
* - `g(_, _, 3)(1, 2)` | ||
* - `g(_, 2, _)(1, 3)` | ||
* - `g(_, 2)(1)(3)` | ||
* - `g(_, 2)(1, 3)` | ||
* - `g(_, 2)(_, 3)(1)` | ||
* | ||
* @constant | ||
* @memberOf R | ||
* @category Function | ||
* @example | ||
* | ||
* var greet = R.replace('{name}', R.__, 'Hello, {name}!'); | ||
* greet('Alice'); //=> 'Hello, Alice!' | ||
*/ | ||
module.exports = {ramda: 'placeholder'}; | ||
},{}],3:[function(require,module,exports){ | ||
},{"ramda/src/curryN":2}],2:[function(require,module,exports){ | ||
var _arity = require('./internal/_arity'); | ||
var _curry1 = require('./internal/_curry1'); | ||
var _curry2 = require('./internal/_curry2'); | ||
var _curryN = require('./internal/_curryN'); | ||
/** | ||
* Wraps a function of any arity (including nullary) in a function that accepts exactly `n` | ||
* parameters. Unlike `nAry`, which passes only `n` arguments to the wrapped function, | ||
* functions produced by `arity` will pass all provided arguments to the wrapped function. | ||
* | ||
* @func | ||
* @memberOf R | ||
* @sig (Number, (* -> *)) -> (* -> *) | ||
* @category Function | ||
* @param {Number} n The desired arity of the returned function. | ||
* @param {Function} fn The function to wrap. | ||
* @return {Function} A new function wrapping `fn`. The new function is | ||
* guaranteed to be of arity `n`. | ||
* @example | ||
* | ||
* var takesTwoArgs = function(a, b) { | ||
* return [a, b]; | ||
* }; | ||
* takesTwoArgs.length; //=> 2 | ||
* takesTwoArgs(1, 2); //=> [1, 2] | ||
* | ||
* var takesOneArg = R.arity(1, takesTwoArgs); | ||
* takesOneArg.length; //=> 1 | ||
* // All arguments are passed through to the wrapped function | ||
* takesOneArg(1, 2); //=> [1, 2] | ||
*/ | ||
module.exports = _curry2(function(n, fn) { | ||
switch (n) { | ||
case 0: return function() {return fn.apply(this, arguments);}; | ||
case 1: return function(a0) {void a0; return fn.apply(this, arguments);}; | ||
case 2: return function(a0, a1) {void a1; return fn.apply(this, arguments);}; | ||
case 3: return function(a0, a1, a2) {void a2; return fn.apply(this, arguments);}; | ||
case 4: return function(a0, a1, a2, a3) {void a3; return fn.apply(this, arguments);}; | ||
case 5: return function(a0, a1, a2, a3, a4) {void a4; return fn.apply(this, arguments);}; | ||
case 6: return function(a0, a1, a2, a3, a4, a5) {void a5; return fn.apply(this, arguments);}; | ||
case 7: return function(a0, a1, a2, a3, a4, a5, a6) {void a6; return fn.apply(this, arguments);}; | ||
case 8: return function(a0, a1, a2, a3, a4, a5, a6, a7) {void a7; return fn.apply(this, arguments);}; | ||
case 9: return function(a0, a1, a2, a3, a4, a5, a6, a7, a8) {void a8; return fn.apply(this, arguments);}; | ||
case 10: return function(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {void a9; return fn.apply(this, arguments);}; | ||
default: throw new Error('First argument to arity must be a non-negative integer no greater than ten'); | ||
} | ||
}); | ||
},{"./internal/_curry2":6}],4:[function(require,module,exports){ | ||
var __ = require('./__'); | ||
var _curry2 = require('./internal/_curry2'); | ||
var _slice = require('./internal/_slice'); | ||
var arity = require('./arity'); | ||
/** | ||
* Returns a curried equivalent of the provided function, with the | ||
@@ -419,33 +347,28 @@ * specified arity. The curried function has two unusual capabilities. | ||
module.exports = _curry2(function curryN(length, fn) { | ||
return arity(length, function() { | ||
var n = arguments.length; | ||
var shortfall = length - n; | ||
var idx = n; | ||
while (--idx >= 0) { | ||
if (arguments[idx] === __) { | ||
shortfall += 1; | ||
} | ||
} | ||
if (shortfall <= 0) { | ||
return fn.apply(this, arguments); | ||
} else { | ||
var initialArgs = _slice(arguments); | ||
return curryN(shortfall, function() { | ||
var currentArgs = _slice(arguments); | ||
var combinedArgs = []; | ||
var idx = -1; | ||
while (++idx < n) { | ||
var val = initialArgs[idx]; | ||
combinedArgs[idx] = (val === __ ? currentArgs.shift() : val); | ||
} | ||
return fn.apply(this, combinedArgs.concat(currentArgs)); | ||
}); | ||
} | ||
}); | ||
if (length === 1) { | ||
return _curry1(fn); | ||
} | ||
return _arity(length, _curryN(length, [], fn)); | ||
}); | ||
},{"./__":2,"./arity":3,"./internal/_curry2":6,"./internal/_slice":7}],5:[function(require,module,exports){ | ||
var __ = require('../__'); | ||
},{"./internal/_arity":3,"./internal/_curry1":4,"./internal/_curry2":5,"./internal/_curryN":6}],3:[function(require,module,exports){ | ||
module.exports = function _arity(n, fn) { | ||
// jshint unused:vars | ||
switch (n) { | ||
case 0: return function() { return fn.apply(this, arguments); }; | ||
case 1: return function(a0) { return fn.apply(this, arguments); }; | ||
case 2: return function(a0, a1) { return fn.apply(this, arguments); }; | ||
case 3: return function(a0, a1, a2) { return fn.apply(this, arguments); }; | ||
case 4: return function(a0, a1, a2, a3) { return fn.apply(this, arguments); }; | ||
case 5: return function(a0, a1, a2, a3, a4) { return fn.apply(this, arguments); }; | ||
case 6: return function(a0, a1, a2, a3, a4, a5) { return fn.apply(this, arguments); }; | ||
case 7: return function(a0, a1, a2, a3, a4, a5, a6) { return fn.apply(this, arguments); }; | ||
case 8: return function(a0, a1, a2, a3, a4, a5, a6, a7) { return fn.apply(this, arguments); }; | ||
case 9: return function(a0, a1, a2, a3, a4, a5, a6, a7, a8) { return fn.apply(this, arguments); }; | ||
case 10: return function(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) { return fn.apply(this, arguments); }; | ||
default: throw new Error('First argument to _arity must be a non-negative integer no greater than ten'); | ||
} | ||
}; | ||
},{}],4:[function(require,module,exports){ | ||
/** | ||
@@ -463,6 +386,6 @@ * Optimized internal two-arity curry function. | ||
return f1; | ||
} else if (a === __) { | ||
} else if (a != null && a['@@functional/placeholder'] === true) { | ||
return f1; | ||
} else { | ||
return fn(a); | ||
return fn.apply(this, arguments); | ||
} | ||
@@ -472,4 +395,3 @@ }; | ||
},{"../__":2}],6:[function(require,module,exports){ | ||
var __ = require('../__'); | ||
},{}],5:[function(require,module,exports){ | ||
var _curry1 = require('./_curry1'); | ||
@@ -491,11 +413,12 @@ | ||
return f2; | ||
} else if (n === 1 && a === __) { | ||
} else if (n === 1 && a != null && a['@@functional/placeholder'] === true) { | ||
return f2; | ||
} else if (n === 1) { | ||
return _curry1(function(b) { return fn(a, b); }); | ||
} else if (n === 2 && a === __ && b === __) { | ||
} else if (n === 2 && a != null && a['@@functional/placeholder'] === true && | ||
b != null && b['@@functional/placeholder'] === true) { | ||
return f2; | ||
} else if (n === 2 && a === __) { | ||
} else if (n === 2 && a != null && a['@@functional/placeholder'] === true) { | ||
return _curry1(function(a) { return fn(a, b); }); | ||
} else if (n === 2 && b === __) { | ||
} else if (n === 2 && b != null && b['@@functional/placeholder'] === true) { | ||
return _curry1(function(b) { return fn(a, b); }); | ||
@@ -508,36 +431,43 @@ } else { | ||
},{"../__":2,"./_curry1":5}],7:[function(require,module,exports){ | ||
},{"./_curry1":4}],6:[function(require,module,exports){ | ||
var _arity = require('./_arity'); | ||
/** | ||
* An optimized, private array `slice` implementation. | ||
* Internal curryN function. | ||
* | ||
* @private | ||
* @param {Arguments|Array} args The array or arguments object to consider. | ||
* @param {Number} [from=0] The array index to slice from, inclusive. | ||
* @param {Number} [to=args.length] The array index to slice to, exclusive. | ||
* @return {Array} A new, sliced array. | ||
* @example | ||
* | ||
* _slice([1, 2, 3, 4, 5], 1, 3); //=> [2, 3] | ||
* | ||
* var firstThreeArgs = function(a, b, c, d) { | ||
* return _slice(arguments, 0, 3); | ||
* }; | ||
* firstThreeArgs(1, 2, 3, 4); //=> [1, 2, 3] | ||
* @category Function | ||
* @param {Number} length The arity of the curried function. | ||
* @return {array} An array of arguments received thus far. | ||
* @param {Function} fn The function to curry. | ||
*/ | ||
module.exports = function _slice(args, from, to) { | ||
switch (arguments.length) { | ||
case 1: return _slice(args, 0, args.length); | ||
case 2: return _slice(args, from, args.length); | ||
default: | ||
var list = []; | ||
var idx = -1; | ||
var len = Math.max(0, Math.min(args.length, to) - from); | ||
while (++idx < len) { | ||
list[idx] = args[from + idx]; | ||
module.exports = function _curryN(length, received, fn) { | ||
return function() { | ||
var combined = []; | ||
var argsIdx = 0; | ||
var left = length; | ||
var combinedIdx = 0; | ||
while (combinedIdx < received.length || argsIdx < arguments.length) { | ||
var result; | ||
if (combinedIdx < received.length && | ||
(received[combinedIdx] == null || | ||
received[combinedIdx]['@@functional/placeholder'] !== true || | ||
argsIdx >= arguments.length)) { | ||
result = received[combinedIdx]; | ||
} else { | ||
result = arguments[argsIdx]; | ||
argsIdx += 1; | ||
} | ||
return list; | ||
} | ||
combined[combinedIdx] = result; | ||
if (result == null || result['@@functional/placeholder'] !== true) { | ||
left -= 1; | ||
} | ||
combinedIdx += 1; | ||
} | ||
return left <= 0 ? fn.apply(this, combined) : _arity(left, _curryN(length, combined, fn)); | ||
}; | ||
}; | ||
},{}]},{},[1])(1) | ||
},{"./_arity":3}]},{},[1])(1) | ||
}); |
@@ -13,8 +13,9 @@ var curryN = require('ramda/src/curryN'); | ||
// Library functions use self callback to accept (null, undefined) update triggers. | ||
function map(f, s) { | ||
return stream([s], function(self) { self(f(s.val)); }); | ||
return combine(function(s, self) { self(f(s.val)); }, [s]); | ||
} | ||
function on(f, s) { | ||
return stream([s], function() { f(s.val); }); | ||
return combine(function(s) { f(s.val); }, [s]); | ||
} | ||
@@ -25,5 +26,5 @@ | ||
var scan = curryN(3, function(f, acc, s) { | ||
var ns = stream([s], function() { | ||
return (acc = f(acc, s())); | ||
}); | ||
var ns = combine(function(s, self) { | ||
self(acc = f(acc, s.val)); | ||
}, [s]); | ||
if (!ns.hasVal) ns(acc); | ||
@@ -34,10 +35,14 @@ return ns; | ||
var merge = curryN(2, function(s1, s2) { | ||
var s = immediate(stream([s1, s2], function(n, changed) { | ||
return changed[0] ? changed[0]() | ||
: s1.hasVal ? s1() | ||
: s2(); | ||
})); | ||
endsOn(stream([s1.end, s2.end], function(self, changed) { | ||
var s = immediate(combine(function(s1, s2, self, changed) { | ||
if (changed[0]) { | ||
self(changed[0]()); | ||
} else if (s1.hasVal) { | ||
self(s1.val); | ||
} else if (s2.hasVal) { | ||
self(s2.val); | ||
} | ||
}, [s1, s2])); | ||
endsOn(combine(function() { | ||
return true; | ||
}), s); | ||
}, [s1.end, s2.end]), s); | ||
return s; | ||
@@ -48,3 +53,3 @@ }); | ||
var s1 = this; | ||
return stream([s1, s2], function() { return s1()(s2()); }); | ||
return combine(function(s1, s2, self) { self(s1.val(s2.val)); }, [s1, s2]); | ||
} | ||
@@ -67,3 +72,4 @@ | ||
inStream = s; | ||
var returnVal = s.fn(s, s.depsChanged); | ||
if (s.depsChanged) s.fnArgs[s.fnArgs.length - 1] = s.depsChanged; | ||
var returnVal = s.fn.apply(s.fn, s.fnArgs); | ||
if (returnVal !== undefined) { | ||
@@ -196,3 +202,3 @@ s(returnVal); | ||
s.depsMet = false; | ||
s.depsChanged = fn.length > 1 ? [] : undefined; | ||
s.depsChanged = deps.length > 0 ? [] : undefined; | ||
s.shouldUpdate = false; | ||
@@ -238,25 +244,30 @@ addListeners(deps, s); | ||
function stream(arg, fn) { | ||
function stream(initialValue) { | ||
var endStream = createDependentStream([], trueFn); | ||
var s = createStream(); | ||
s.end = endStream; | ||
s.fnArgs = []; | ||
endStream.listeners.push(s); | ||
if (arguments.length > 0) s(initialValue); | ||
return s; | ||
} | ||
function combine(fn, streams) { | ||
var i, s, deps, depEndStreams; | ||
var endStream = createDependentStream([], trueFn); | ||
if (arguments.length > 1) { | ||
deps = []; depEndStreams = []; | ||
for (i = 0; i < arg.length; ++i) { | ||
if (arg[i] !== undefined) { | ||
deps.push(arg[i]); | ||
if (arg[i].end !== undefined) depEndStreams.push(arg[i].end); | ||
} | ||
deps = []; depEndStreams = []; | ||
for (i = 0; i < streams.length; ++i) { | ||
if (streams[i] !== undefined) { | ||
deps.push(streams[i]); | ||
if (streams[i].end !== undefined) depEndStreams.push(streams[i].end); | ||
} | ||
s = createDependentStream(deps, fn); | ||
s.end = endStream; | ||
endStream.listeners.push(s); | ||
addListeners(depEndStreams, endStream); | ||
endStream.deps = depEndStreams; | ||
updateStream(s); | ||
} else { | ||
s = createStream(); | ||
s.end = endStream; | ||
endStream.listeners.push(s); | ||
if (arguments.length === 1) s(arg); | ||
} | ||
s = createDependentStream(deps, fn); | ||
s.depsChanged = []; | ||
s.fnArgs = s.deps.concat([s, s.depsChanged]); | ||
s.end = endStream; | ||
endStream.listeners.push(s); | ||
addListeners(depEndStreams, endStream); | ||
endStream.deps = depEndStreams; | ||
updateStream(s); | ||
return s; | ||
@@ -267,4 +278,4 @@ } | ||
xform = xform(new StreamTransformer()); | ||
return stream([source], function(self) { | ||
var res = xform['@@transducer/step'](undefined, source()); | ||
return combine(function(source, self) { | ||
var res = xform['@@transducer/step'](undefined, source.val); | ||
if (res && res['@@transducer/reduced'] === true) { | ||
@@ -276,3 +287,3 @@ self.end(true); | ||
} | ||
}); | ||
}, [source]); | ||
}); | ||
@@ -287,2 +298,3 @@ | ||
stream: stream, | ||
combine: curryN(2, combine), | ||
isStream: isStream, | ||
@@ -289,0 +301,0 @@ transduce: transduce, |
@@ -1,7 +0,7 @@ | ||
var flyd = require('flyd'); | ||
var flyd = require('../../lib'); | ||
module.exports = function(dur, s) { | ||
module.exports = flyd.curryN(2, function(dur, s) { | ||
var scheduled; | ||
var buffer = []; | ||
return flyd.stream([s], function(self) { | ||
return flyd.combine(function(s, self) { | ||
buffer.push(s()); | ||
@@ -13,3 +13,3 @@ clearTimeout(scheduled); | ||
}, dur); | ||
}); | ||
}; | ||
}, [s]); | ||
}); |
var assert = require('assert'); | ||
var flyd = require('../../../flyd'); | ||
var flyd = require('../../../lib'); | ||
var stream = flyd.stream; | ||
@@ -4,0 +4,0 @@ |
@@ -1,2 +0,2 @@ | ||
var flyd = require('flyd'); | ||
var flyd = require('../../lib'); | ||
@@ -7,5 +7,5 @@ var previous = require('../previous'); | ||
var prevS = previous(s); | ||
return flyd.stream([s, prevS], function (self) { | ||
return flyd.combine(function (self) { | ||
return diffFunc(prevS(), s()); | ||
}); | ||
}, [s, prevS]); | ||
}; |
var assert = require('assert'); | ||
var flyd = require('../../../flyd'); | ||
var flyd = require('../../../lib'); | ||
var stream = flyd.stream; | ||
@@ -4,0 +4,0 @@ |
@@ -1,6 +0,6 @@ | ||
var flyd = require('flyd'); | ||
var flyd = require('../../lib'); | ||
function dropRepeatsWith(eq, s) { | ||
var prev; | ||
return flyd.stream([s], function(self) { | ||
return flyd.combine(function(s, self) { | ||
if (!eq(s.val, prev)) { | ||
@@ -10,3 +10,3 @@ self(s.val); | ||
} | ||
}); | ||
}, [s]); | ||
} | ||
@@ -13,0 +13,0 @@ |
@@ -1,2 +0,2 @@ | ||
var flyd = require('../../../flyd'); | ||
var flyd = require('../../../lib'); | ||
var stream = flyd.stream; | ||
@@ -6,3 +6,3 @@ var dropRepeats = require('../').dropRepeats; | ||
var R = require('ramda'); | ||
var assert = require('chai').assert; | ||
var assert = require('assert'); | ||
@@ -9,0 +9,0 @@ var collect = flyd.scan(R.flip(R.append), []); |
@@ -1,2 +0,2 @@ | ||
var flyd = require('flyd'); | ||
var flyd = require('../../lib'); | ||
@@ -3,0 +3,0 @@ module.exports = function(dur) { |
var assert = require('assert'); | ||
var flyd = require('../../../flyd'); | ||
var flyd = require('../../../lib'); | ||
var every = require('../index.js'); | ||
@@ -4,0 +4,0 @@ |
@@ -1,7 +0,7 @@ | ||
var flyd = require('flyd'); | ||
var flyd = require('../../lib'); | ||
module.exports = flyd.curryN(2, function(fn, s) { | ||
return flyd.stream([s], function(self) { | ||
return flyd.combine(function(s, self) { | ||
if (fn(s())) self(s.val); | ||
}); | ||
}, [s]); | ||
}); |
var assert = require('assert'); | ||
var flyd = require('../../../flyd'); | ||
var flyd = require('../../../lib'); | ||
@@ -4,0 +4,0 @@ var filter = require('../index.js'); |
@@ -1,7 +0,7 @@ | ||
var flyd = require('flyd'); | ||
var flyd = require('../../lib'); | ||
module.exports = function(f, s) { | ||
return flyd.stream([s], function(own) { | ||
return flyd.combine(function(s, own) { | ||
flyd.map(own, f(s())); | ||
}); | ||
}, [s]); | ||
}; |
@@ -1,2 +0,2 @@ | ||
var flyd = require('flyd'); | ||
var flyd = require('../../lib'); | ||
@@ -3,0 +3,0 @@ module.exports = flyd.curryN(2, function(targ, fn) { |
var assert = require('assert'); | ||
var flyd = require('../../../flyd'); | ||
var flyd = require('../../../lib'); | ||
var forwardTo = require('../index.js'); | ||
@@ -4,0 +4,0 @@ |
@@ -1,6 +0,6 @@ | ||
var flyd = require('flyd'); | ||
var flyd = require('../../lib'); | ||
module.exports = flyd.curryN(2, function(dur, s) { | ||
var values = []; | ||
return flyd.stream([s], function(self) { | ||
return flyd.combine(function(s, self) { | ||
setTimeout(function() { | ||
@@ -10,3 +10,3 @@ self(values = values.slice(1)); | ||
return (values = values.concat([s()])); | ||
}); | ||
}, [s]); | ||
}); |
var assert = require('assert'); | ||
var flyd = require('../../flyd'); | ||
var flyd = require('../../../lib'); | ||
var stream = flyd.stream; | ||
@@ -4,0 +4,0 @@ |
@@ -1,8 +0,8 @@ | ||
var flyd = require('flyd'); | ||
var flyd = require('../../lib'); | ||
// Stream bool -> Stream a -> Stream a | ||
module.exports = flyd.curryN(2, function(sBool, sA) { | ||
return flyd.stream([sA], function(self) { | ||
return flyd.combine(function(sA, self) { | ||
if (sBool() !== false) self(sA()); | ||
}); | ||
}, [sA]); | ||
}); |
var assert = require('assert'); | ||
var flyd = require('flyd'); | ||
var flyd = require('../../../lib'); | ||
var stream = flyd.stream; | ||
@@ -4,0 +4,0 @@ |
@@ -1,2 +0,2 @@ | ||
var flyd = require('flyd'); | ||
var flyd = require('../../lib'); | ||
@@ -6,6 +6,6 @@ module.exports = function(f /* , streams */) { | ||
var vals = []; | ||
return flyd.stream(streams, function() { | ||
return flyd.combine(function() { | ||
for (var i = 0; i < streams.length; ++i) vals[i] = streams[i](); | ||
return f.apply(null, vals); | ||
}); | ||
}, streams); | ||
}; |
var assert = require('assert'); | ||
var flyd = require('flyd'); | ||
var flyd = require('../../../lib'); | ||
var stream = flyd.stream; | ||
@@ -4,0 +4,0 @@ var lift = require('../index.js'); |
@@ -1,2 +0,2 @@ | ||
var flyd = require('flyd'); | ||
var flyd = require('../../lib'); | ||
@@ -35,5 +35,5 @@ function isPlainObject(obj) { | ||
}); | ||
return flyd.stream(streams, function() { | ||
return flyd.combine(function() { | ||
return extractProps(obj); | ||
}); | ||
}, streams); | ||
}; | ||
@@ -40,0 +40,0 @@ |
var assert = require('assert'); | ||
var flyd = require('flyd'); | ||
var flyd = require('../../../lib'); | ||
var stream = flyd.stream; | ||
@@ -4,0 +4,0 @@ |
@@ -1,9 +0,9 @@ | ||
var flyd = require('flyd'); | ||
var flyd = require('../../lib'); | ||
module.exports = function (s) { | ||
var previousValue; | ||
return flyd.stream([s], skipFirstCall(function (self) { | ||
return flyd.combine(skipFirstCall(function(s, self) { | ||
self(previousValue); | ||
previousValue = s(); | ||
})); | ||
}), [s]); | ||
}; | ||
@@ -10,0 +10,0 @@ |
var assert = require('assert'); | ||
var flyd = require('flyd'); | ||
var flyd = require('../../../lib'); | ||
var stream = flyd.stream; | ||
@@ -4,0 +4,0 @@ |
@@ -1,7 +0,7 @@ | ||
var flyd = require('flyd'); | ||
var flyd = require('../../lib'); | ||
module.exports = flyd.curryN(2, function(s1, s2) { | ||
return flyd.stream([s1], function() { | ||
return flyd.combine(function(s1) { | ||
return s2(); | ||
}); | ||
}, [s1]); | ||
}); |
var assert = require('assert'); | ||
var flyd = require('flyd'); | ||
var flyd = require('../../../lib'); | ||
var stream = flyd.stream; | ||
@@ -4,0 +4,0 @@ |
@@ -1,13 +0,20 @@ | ||
var flyd = require('flyd'); | ||
var flyd = require('../../lib'); | ||
module.exports = flyd.curryN(2, function(pairs, acc) { | ||
var streams = pairs.map(function(p) { return p[0]; }); | ||
var fns = pairs.map(function(p) { return p[1]; }); | ||
return flyd.stream(streams, function(self, changed) { | ||
if (changed.length > 0) { | ||
var idx = streams.indexOf(changed[0]); | ||
acc = fns[idx](acc, changed[0]()); | ||
// use immediate because we want each stream to fire regardless of if the others have ever had a value | ||
return flyd.immediate(flyd.combine(function() { | ||
var changed = arguments[arguments.length - 1]; | ||
var self = arguments[arguments.length - 2]; | ||
// because of atomic updates we can have more than one changed | ||
// meaning more than one function should be fired, lets do it in order so its predictable | ||
for(var p = 0; p < pairs.length; p++) { | ||
// because changed is an array of references it doesn't matter if we pull the first match in the case of multiple matches | ||
var idx = changed.indexOf(pairs[p][0]); | ||
if (idx !== -1) { | ||
acc = pairs[p][1](acc, changed[idx]()); | ||
} | ||
} | ||
return acc; | ||
}, true); | ||
}, streams)); | ||
}); |
var assert = require('assert'); | ||
var flyd = require('flyd'); | ||
var flyd = require('../../../lib'); | ||
var stream = flyd.stream; | ||
@@ -4,0 +4,0 @@ |
@@ -1,11 +0,11 @@ | ||
var flyd = require('flyd'); | ||
var flyd = require('../../lib'); | ||
module.exports = function(s) { | ||
var inner; | ||
return flyd.stream([s], function(self) { | ||
return flyd.combine(function(s, self) { | ||
inner = s(); | ||
flyd.endsOn(flyd.merge(s, inner.end), flyd.stream([inner], function() { | ||
flyd.endsOn(flyd.merge(s, inner.end), flyd.combine(function(inner) { | ||
self(inner()); | ||
})); | ||
}); | ||
}, [inner])); | ||
}, [s]); | ||
}; |
@@ -1,2 +0,2 @@ | ||
var flyd = require('../../../flyd'); | ||
var flyd = require('../../../lib'); | ||
var stream = flyd.stream; | ||
@@ -3,0 +3,0 @@ var assert = require('assert'); |
@@ -1,7 +0,7 @@ | ||
var flyd = require('flyd'); | ||
var flyd = require('../../lib'); | ||
module.exports = function(src, term) { | ||
return flyd.endsOn(flyd.merge(term, src.end), flyd.stream([src], function(self) { | ||
return flyd.endsOn(flyd.merge(term, src.end), flyd.combine(function(src, self) { | ||
self(src()); | ||
})); | ||
}, [src])); | ||
}; |
@@ -1,6 +0,6 @@ | ||
var flyd = require('../../flyd/flyd.js'); | ||
var flyd = require('../../../lib'); | ||
var stream = flyd.stream; | ||
var assert = require('assert'); | ||
var takeUntil = require('../takeuntil.js'); | ||
var takeUntil = require('../index'); | ||
@@ -7,0 +7,0 @@ describe('takeUntil', function() { |
{ | ||
"name": "flyd", | ||
"version": "0.1.17", | ||
"version": "0.2.0", | ||
"description": "The less is more, modular, functional reactive programming library", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -120,6 +120,7 @@ # Flyd | ||
Streams can depend on other streams. Instead of calling `stream` with a value | ||
as in the above examples we can pass it a list of dependencies and a function. | ||
The function should produce a value based on its dependencies. This new | ||
returned value results in a new stream. | ||
Streams can depend on other streams. Use `var combined = flyd.combine(combineFn, [a, b, c, ...])`. | ||
The `combineFn` function will be called as `(a, b, c, ..., self, changed) => v`, | ||
where `a, b, c, ...` is a spread of each dependency, `self` is a reference to the | ||
combine stream itself, and `changed` is an array of streams that were atomically | ||
updated. | ||
@@ -137,5 +138,5 @@ Flyd automatically updates the stream whenever a dependency changes. This | ||
// and with its value given by the two added together. | ||
var sum = flyd.stream([x, y], function() { | ||
var sum = flyd.combine(function(x, y) { | ||
return x() + y(); | ||
}); | ||
}, [x, y]); | ||
// `sum` is automatically recalculated whenever the streams it depends on changes. | ||
@@ -154,8 +155,8 @@ x(12); | ||
var y = flyd.stream(6); | ||
var squareX = flyd.stream([x], function() { | ||
var squareX = flyd.combine(function(x) { | ||
return x() * x(); | ||
}); | ||
var squareXPlusY = flyd.stream([y, squareX], function() { | ||
}, [x]); | ||
var squareXPlusY = flyd.combine(function(y, squareX) { | ||
return y() + squareX(); | ||
}); | ||
}, [y, squareX]); | ||
console.log(squareXPlusY()); // logs 22 | ||
@@ -166,3 +167,3 @@ x(2); | ||
The body of a dependent stream is called with two parameters: itself and a list | ||
The body of a dependent stream is called with the spread of: each dependency, itself, and a list | ||
of the dependencies that have changed since its last invocation (due to [atomic | ||
@@ -175,5 +176,5 @@ updates](#atomic-updates) several streams could have changed). | ||
var y = flyd.stream(2); | ||
var sum = flyd.stream([x, y], function(sum, changed) { | ||
var sum = flyd.combine(function(x, y, self, changed) { | ||
// The stream can read from itself | ||
console.log('Last sum was ' + sum()); | ||
console.log('Last sum was ' + self()); | ||
// On the initial call no streams has changed and `changed` will be [] | ||
@@ -185,5 +186,11 @@ changed.map(function(s) { | ||
return x() + y(); | ||
}); | ||
}, [x, y]); | ||
``` | ||
*Note* Returning `undefined` in the `combineFn` will not trigger an upodate | ||
to the stream. To trigger on undefined, update directly: | ||
``` | ||
flyd.combine((_, self, changed) => { self(undefined); }, [depStream]); | ||
``` | ||
### Using callback APIs for asynchronous operations | ||
@@ -196,9 +203,9 @@ | ||
var urls = flyd.stream('/something.json'); | ||
var responses = flyd.stream([urls], function(resp) { | ||
makeRequest(urls(), resp); | ||
}); | ||
flyd.stream([responses], function() { | ||
var responses = flyd.combine(function(urls, self) { | ||
makeRequest(urls(), self); | ||
}, [urls]); | ||
flyd.combine(function(responses) { | ||
console.log('Received response!'); | ||
console.log(responses()); | ||
}); | ||
}, [responses]); | ||
``` | ||
@@ -223,6 +230,6 @@ | ||
}); | ||
flyd.stream([responses], function() { | ||
flyd.combine(function(responses) { | ||
console.log('Received response!'); | ||
console.log(responses()); | ||
}); | ||
}, [responses]); | ||
``` | ||
@@ -239,5 +246,5 @@ | ||
var mapStream = function(f, s) { | ||
return flyd.stream([s], function() { | ||
return flyd.combine(function(s) { | ||
return f(s()); | ||
}); | ||
}, [s]); | ||
}; | ||
@@ -259,6 +266,6 @@ ``` | ||
var scanStream = function(f, acc, s) { | ||
return flyd.stream([s], function() { | ||
return flyd.combine(function(s) { | ||
acc = f(acc, s()); | ||
return acc; | ||
}); | ||
}, [s]); | ||
}; | ||
@@ -296,5 +303,5 @@ ``` | ||
var n2 = flyd.stream(); | ||
var sum = flyd.stream([n1, n2], function() { | ||
var sum = flyd.combine(function(n1, n2) { | ||
return n1() + n2(); | ||
}); | ||
}, [n1, n2]); | ||
``` | ||
@@ -310,5 +317,5 @@ | ||
var killer = flyd.stream(); | ||
var square = flyd.endsOn(flyd.merge(number.end, killer), flyd.stream([number], function() { | ||
var square = flyd.endsOn(flyd.merge(number.end, killer), flyd.stream(function(number) { | ||
return number() * number(); | ||
})); | ||
}, [number])); | ||
``` | ||
@@ -344,3 +351,3 @@ | ||
### flyd.stream(dependencies, body) | ||
### flyd.combine(body, dependencies) | ||
@@ -351,3 +358,3 @@ Creates a new dependent stream. | ||
`[Stream *] -> (Stream b -> [Stream *] -> b) -> Stream b` | ||
`(...Stream * -> Stream b -> b) -> [Stream *] -> Stream b` | ||
@@ -358,5 +365,5 @@ __Example__ | ||
var n2 = flyd.stream(0); | ||
var max = flyd.stream([n1, n2], function(self, changed) { | ||
var max = flyd.combine(function(n1, n2, self, changed) { | ||
return n1() > n2() ? n1() : n2(); | ||
}); | ||
}, [n1, n2]); | ||
``` | ||
@@ -395,5 +402,5 @@ | ||
var s = flyd.stream(); | ||
var hasItems = flyd.immediate(flyd.stream([s], function() { | ||
var hasItems = flyd.immediate(flyd.stream(function(s) { | ||
return s() !== undefined && s().length > 0; | ||
}); | ||
}, [s]); | ||
console.log(hasItems()); // logs `false`. Had `immediate` not been | ||
@@ -421,5 +428,5 @@ // used `hasItems()` would've returned `undefined` | ||
// `double` ends when `n` ends or when `killer` emits any value | ||
var double = flyd.endsOn(flyd.merge(n.end, killer), flyd.stream([n], function() { | ||
var double = flyd.endsOn(flyd.merge(n.end, killer), flyd.combine(function(n) { | ||
return 2 * n(); | ||
}); | ||
}, [n]); | ||
``` | ||
@@ -513,3 +520,3 @@ | ||
var s2 = flyd.transduce(tx, s1); | ||
flyd.stream([s2], function() { results.push(s2()); }); | ||
flyd.combine(function(s2) { results.push(s2()); }, [s2]); | ||
s1(1)(1)(2)(3)(3)(3)(4); | ||
@@ -673,7 +680,7 @@ results; // [2, 4, 6, 8] | ||
var a = flyd.stream(1); | ||
var b = flyd.stream([a], function() { return a() * 2; }); | ||
var c = flyd.stream([a], function() { return a() + 4; }); | ||
var d = flyd.stream([b, c], function(self, ch) { | ||
var b = flyd.combine(function(a) { return a() * 2; }, [a]); | ||
var c = flyd.combine(function(a) { return a() + 4; }, [a]); | ||
var d = flyd.combine(function(b, c, self, ch) { | ||
result.push(b() + c()); | ||
}); | ||
}, [b, c]); | ||
``` | ||
@@ -680,0 +687,0 @@ |
@@ -8,3 +8,9 @@ var assert = require('assert'); | ||
var stream = flyd.stream; | ||
var combine = flyd.combine; | ||
// Some combinators | ||
function doubleFn(x) { return x() * 2; } | ||
function sumFn(x, y) { return x() + y(); } | ||
function identityLift(x) { return x(); } | ||
describe('stream', function() { | ||
@@ -26,146 +32,2 @@ it('can be set with initial value', function() { | ||
}); | ||
it('updates dependencies', function() { | ||
var x = stream(3); | ||
var x2 = stream([x], function() { | ||
return x() * 2; | ||
}); | ||
assert.equal(x2(), x() * 2); | ||
}); | ||
it('can set result by returning value', function() { | ||
var x = stream(3); | ||
var y = stream(4); | ||
var sum = stream([x, y], function() { | ||
return x() + y(); | ||
}); | ||
assert.equal(sum(), x() + y()); | ||
}); | ||
it('is updated when dependencies change', function() { | ||
var x = stream(3); | ||
var y = stream(4); | ||
var sum = stream([x, y], function(s) { | ||
return x() + y(); | ||
}); | ||
assert.equal(sum(), x() + y()); // 7 | ||
x(12); | ||
assert.equal(sum(), x() + y()); // 16 | ||
y(8); | ||
assert.equal(sum(), x() + y()); // 20 | ||
}); | ||
it('can set result by calling callback', function() { | ||
var x = stream(3); | ||
var y = stream(4); | ||
var times = 0; | ||
var sum = stream([x, y], function(s) { | ||
s(x() + y()); | ||
}); | ||
stream([sum], function() { | ||
times++; | ||
}); | ||
assert.equal(sum(), x() + y()); // 7 | ||
x(12); | ||
assert.equal(sum(), x() + y()); // 16 | ||
y(8); | ||
assert.equal(sum(), x() + y()); // 20 | ||
assert.equal(times, 3); | ||
}); | ||
it('is not called until dependencies have value', function() { | ||
var x = stream(); | ||
var y = stream(); | ||
var called = 0; | ||
var sum = stream([x, y], function(s) { | ||
called++; | ||
return x() + y(); | ||
}); | ||
x(2); x(1); y(2); y(4); x(2); | ||
assert.equal(called, 3); | ||
}); | ||
it('streams can lead into other streams', function() { | ||
var x = stream(3); | ||
var y = stream(4); | ||
var sum = stream([x, y], function() { | ||
return x() + y(); | ||
}); | ||
var twiceSum = stream([sum], function() { | ||
return sum() * 2; | ||
}); | ||
var sumPlusDoubleSum = stream([twiceSum, sum], function() { | ||
return twiceSum() + sum(); | ||
}); | ||
x(12); | ||
assert.equal(sumPlusDoubleSum(), sum() * 3); | ||
y(3); | ||
assert.equal(sumPlusDoubleSum(), sum() * 3); | ||
x(2); | ||
assert.equal(sumPlusDoubleSum(), sum() * 3); | ||
assert.equal(sumPlusDoubleSum(), (2 + 3) * 3); | ||
}); | ||
it('can get its own value', function() { | ||
var num = stream(0); | ||
var sum = stream([num], function(sum) { | ||
return (sum() || 0) + num(); | ||
}); | ||
num(2)(3)(8)(7); | ||
assert.equal(sum(), 20); | ||
}); | ||
it('is called with changed streams', function() { | ||
var s1 = stream(0); | ||
var s2 = stream(0); | ||
var result = []; | ||
var dependend = stream([s1, s2], function(d, changed) { | ||
if (changed[0] === s1) result.push(1); | ||
if (changed[0] === s2) result.push(2); | ||
}); | ||
s1(1); | ||
s2(1); | ||
s2(1); | ||
s1(1); | ||
s2(1); | ||
s1(1); | ||
assert.deepEqual(result, [1, 2, 2, 1, 2, 1]); | ||
}); | ||
it('handles dependencies when streams are triggered in streams', function() { | ||
var x = stream(4); | ||
var y = stream(3); | ||
var z = stream(1); | ||
var doubleX = stream([x], function() { | ||
return x() * 2; | ||
}); | ||
var setAndSum = stream([y, z], function() { | ||
x(3); | ||
return z() + y(); | ||
}); | ||
z(4); | ||
assert.equal(setAndSum(), 7); | ||
}); | ||
it('executes to the end before handlers are triggered', function() { | ||
var order = []; | ||
var x = stream(4); | ||
var y = stream(3); | ||
var doubleX = stream([x], function dx() { | ||
if (x() === 3) order.push(2); | ||
return x() * 2; | ||
}); | ||
var setAndY = stream([y], function sy() { | ||
x(3); | ||
order.push(1); | ||
return y(); | ||
}); | ||
assert.deepEqual(order, [1, 2]); | ||
}); | ||
it('with static deps executes to the end', function() { | ||
var order = []; | ||
var x = stream(4); | ||
var y = stream(3); | ||
var doubleX = stream([x], function() { | ||
if (x() === 3) order.push(2); | ||
return x() * 2; | ||
}); | ||
var setAndY = stream([y], function() { | ||
x(3); | ||
order.push(1); | ||
return y(); | ||
}); | ||
assert.equal(order[0], 1); | ||
assert.equal(order[1], 2); | ||
}); | ||
it("let's explicit `undefined` flow down streams", function() { | ||
@@ -199,28 +61,174 @@ var result = []; | ||
}); | ||
it('can filter values', function() { | ||
var result = []; | ||
var n = stream(0); | ||
var lrg5 = stream([n], function() { | ||
if (n() > 5) return n(); | ||
describe('dependent streams', function() { | ||
it('updates dependencies', function() { | ||
var x = stream(3); | ||
var x2 = combine(doubleFn, [x]); | ||
assert.equal(x2(), x() * 2); | ||
}); | ||
flyd.map(function(v) { result.push(v); }, lrg5); | ||
n(4)(6)(2)(8)(3)(4); | ||
assert.deepEqual(result, [6, 8]); | ||
}); | ||
it('can set another stream\'s value multiple times from inside a stream', function() { | ||
var result = []; | ||
var a = stream(); | ||
var b = stream(); | ||
stream([b], function() { | ||
a(b()); | ||
a(); | ||
a(b() + 1); | ||
assert.equal(a(), 2); | ||
it('can set result by returning value', function() { | ||
var x = stream(3); | ||
var y = stream(4); | ||
var sum = combine(sumFn, [x, y]); | ||
assert.equal(sum(), x() + y()); | ||
}); | ||
stream([a], function(self) { | ||
result.push(a()); | ||
it('is updated when dependencies change', function() { | ||
var x = stream(3); | ||
var y = stream(4); | ||
var sum = combine(sumFn, [x, y]); | ||
assert.equal(sum(), x() + y()); // 7 | ||
x(12); | ||
assert.equal(sum(), x() + y()); // 16 | ||
y(8); | ||
assert.equal(sum(), x() + y()); // 20 | ||
}); | ||
b(1); | ||
assert.deepEqual(result, [1, 2]); | ||
it('can set result by calling callback', function() { | ||
var x = stream(3); | ||
var y = stream(4); | ||
var times = 0; | ||
var sum = combine(sumFn, [x, y]); | ||
combine(function() { | ||
times++; | ||
}, [sum]); | ||
assert.equal(sum(), x() + y()); // 7 | ||
x(12); | ||
assert.equal(sum(), x() + y()); // 16 | ||
y(8); | ||
assert.equal(sum(), x() + y()); // 20 | ||
assert.equal(times, 3); | ||
}); | ||
it('is not called until dependencies have value', function() { | ||
var x = stream(); | ||
var y = stream(); | ||
var called = 0; | ||
var sum = combine(function(x, y) { | ||
called++; | ||
return x() + y(); | ||
}, [x, y]); | ||
x(2); x(1); y(2); y(4); x(2); | ||
assert.equal(called, 3); | ||
}); | ||
it('streams can lead into other streams', function() { | ||
var x = stream(3); | ||
var y = stream(4); | ||
var sum = combine(sumFn, [x, y]); | ||
var twiceSum = combine(doubleFn, [sum]); | ||
var sumPlusDoubleSum = combine(sumFn, [twiceSum, sum]); | ||
x(12); | ||
assert.equal(sumPlusDoubleSum(), sum() * 3); | ||
y(3); | ||
assert.equal(sumPlusDoubleSum(), sum() * 3); | ||
x(2); | ||
assert.equal(sumPlusDoubleSum(), sum() * 3); | ||
assert.equal(sumPlusDoubleSum(), (2 + 3) * 3); | ||
}); | ||
it('can get its own value', function() { | ||
var num = stream(0); | ||
var sum = combine(function(num, self) { | ||
return (self() || 0) + num(); | ||
}, [num]); | ||
num(2)(3)(8)(7); | ||
assert.equal(sum(), 20); | ||
}); | ||
it('is called with changed streams', function() { | ||
var s1 = stream(0); | ||
var s2 = stream(0); | ||
var result = []; | ||
var dependend = combine(function(s1, s2, self, changed) { | ||
if (changed[0] === s1) result.push(1); | ||
if (changed[0] === s2) result.push(2); | ||
}, [s1, s2]); | ||
s1(1); | ||
s2(1); | ||
s2(1); | ||
s1(1); | ||
s2(1); | ||
s1(1); | ||
assert.deepEqual(result, [1, 2, 2, 1, 2, 1]); | ||
}); | ||
it('handles dependencies when streams are triggered in streams', function() { | ||
var x = stream(4); | ||
var y = stream(3); | ||
var z = stream(1); | ||
var doubleX = combine(doubleFn, [x]); | ||
var setAndSum = combine(function(y, z) { | ||
x(3); | ||
return z() + y(); | ||
}, [y, z]); | ||
z(4); | ||
assert.equal(setAndSum(), 7); | ||
assert.equal(doubleX(), 6); | ||
}); | ||
it('executes to the end before handlers are triggered', function() { | ||
var order = []; | ||
var x = stream(4); | ||
var y = stream(3); | ||
var doubleX = combine(function dx(x) { | ||
if (x() === 3) order.push(2); | ||
return x() * 2; | ||
}, [x]); | ||
var setAndY = combine(function sy(y) { | ||
x(3); | ||
order.push(1); | ||
return y(); | ||
}, [y]); | ||
assert.deepEqual(order, [1, 2]); | ||
}); | ||
it('with static deps executes to the end', function() { | ||
var order = []; | ||
var x = stream(4); | ||
var y = stream(3); | ||
var doubleX = combine(function(x) { | ||
if (x() === 3) order.push(2); | ||
return x() * 2; | ||
}, [x]); | ||
var setAndY = combine(function(y) { | ||
x(3); | ||
order.push(1); | ||
return y(); | ||
}, [y]); | ||
assert.equal(order[0], 1); | ||
assert.equal(order[1], 2); | ||
}); | ||
it('can filter values', function() { | ||
var result = []; | ||
var n = stream(0); | ||
var lrg5 = combine(function(n) { | ||
if (n() > 5) return n(); | ||
}, [n]); | ||
flyd.map(function(v) { result.push(v); }, lrg5); | ||
n(4)(6)(2)(8)(3)(4); | ||
assert.deepEqual(result, [6, 8]); | ||
}); | ||
it('can set another stream\'s value multiple times from inside a stream', function() { | ||
var result = []; | ||
var a = stream(); | ||
var b = stream(); | ||
combine(function(b) { | ||
a(b()); | ||
a(); | ||
a(b() + 1); | ||
assert.equal(a(), 2); | ||
}, [b]); | ||
combine(function(a) { | ||
result.push(a()); | ||
}, [a]); | ||
b(1); | ||
assert.deepEqual(result, [1, 2]); | ||
}); | ||
it('can combine streams and project deps as args', function() { | ||
var a = flyd.stream(); | ||
var b = flyd.stream(0); | ||
var collect = function(x, y, self){ return (self() || []).concat([x(), y()]); }; | ||
var history = flyd.combine(collect, [a, b]); | ||
a(1)(2); // [1, 0, 2, 0] | ||
b(3); // [1, 0, 2, 0, 2, 3] | ||
a(4); // [1, 0, 2, 0, 2, 3, 4, 3] | ||
assert.deepEqual(history(), [ | ||
1, 0, 2, 0, 2, 3, 4, 3 | ||
]); | ||
}); | ||
}); | ||
describe('ending a stream', function() { | ||
@@ -236,5 +244,5 @@ it('works for streams without dependencies', function() { | ||
var y = stream(2); | ||
var sum = stream([y, x], function() { | ||
var sum = combine(function(x, y) { | ||
return y() * x(); | ||
}); | ||
}, [x, y]); | ||
assert.equal(y.listeners.length, 1); | ||
@@ -249,8 +257,4 @@ assert.equal(x.listeners.length, 1); | ||
var x = stream(3); | ||
var y = stream([x], function() { | ||
return 2 * x(); | ||
}); | ||
var z = stream([y], function() { | ||
return 2 * y(); | ||
}); | ||
var y = combine(doubleFn, [x]); | ||
var z = combine(doubleFn, [y]); | ||
assert.equal(z(), x() * 2 * 2); | ||
@@ -266,8 +270,10 @@ x.end(true); | ||
var x = stream(3); | ||
var whenX2 = stream([x], function() { if (x() === 0) return true; }); | ||
var y = stream([x], function(self) { | ||
return x(); | ||
}); | ||
var whenX2 = combine(function(x) { | ||
if (x() === 0) { | ||
return true; | ||
} | ||
}, [x]); | ||
var y = combine(identityLift, [x]); | ||
flyd.endsOn(whenX2, y); | ||
var z = stream([y], function() { return y(); }); | ||
var z = combine(identityLift, [y]); | ||
assert.equal(y(), z()); | ||
@@ -289,5 +295,3 @@ x(2); | ||
var x = stream(1); | ||
var y = flyd.endsOn(killer, stream([x], function(self) { | ||
return 2 * x(); | ||
})); | ||
var y = flyd.endsOn(killer, combine(doubleFn, [x])); | ||
x(2); | ||
@@ -300,5 +304,3 @@ assert.equal(undefined, y.end()); | ||
var x = stream(1); | ||
var y = flyd.endsOn(killer, stream([x], function(self) { | ||
return 2 * x(); | ||
})); | ||
var y = flyd.endsOn(killer, combine(doubleFn, [x])); | ||
assert.equal(false, y.end.hasVal); | ||
@@ -311,6 +313,6 @@ }); | ||
var x = stream(1); | ||
var y = flyd.endsOn(killer1, stream([x], function(self) { | ||
return 2 * x(); | ||
})); | ||
flyd.map(function() { ended = true; }, y.end); | ||
var y = flyd.endsOn(killer1, combine(doubleFn, [x])); | ||
flyd.map(function() { | ||
ended = true; | ||
}, y.end); | ||
flyd.endsOn(killer2, y); | ||
@@ -328,9 +330,10 @@ killer2(true); | ||
}); | ||
describe('promise integration', function() { | ||
it('pushes result of promise down the stream', function(done) { | ||
var s = stream(); | ||
stream([s], function() { | ||
combine(function(s) { | ||
assert.equal(s(), 12); | ||
done(); | ||
}); | ||
}, [s]); | ||
s(Promise.resolve(12)); | ||
@@ -340,6 +343,6 @@ }); | ||
var s = stream(); | ||
stream([s], function() { | ||
combine(function(s) { | ||
assert.equal(s(), 12); | ||
done(); | ||
}); | ||
}, [s]); | ||
s(new Promise(function(res, rej) { | ||
@@ -354,2 +357,3 @@ setTimeout(function() { | ||
}); | ||
describe('on', function() { | ||
@@ -365,2 +369,3 @@ it('is invoked when stream changes', function() { | ||
}); | ||
describe('map', function() { | ||
@@ -417,2 +422,3 @@ it('maps a function', function() { | ||
}); | ||
describe('scan', function() { | ||
@@ -443,3 +449,14 @@ it('has initial acc as value when stream is undefined', function() { | ||
}); | ||
it('passes undefined', function() { | ||
var x = stream(); | ||
var scan = flyd.scan(function(acc, x){ | ||
return acc.concat([x]); | ||
}, [], x); | ||
x(1)(2)(undefined)(3)(4); | ||
assert.deepEqual(scan(), [1, 2, undefined, 3, 4]); | ||
}); | ||
}); | ||
describe('merge', function() { | ||
@@ -451,5 +468,5 @@ it('can sum streams of integers', function() { | ||
var merged = flyd.merge(s1, s2); | ||
stream([merged], function() { | ||
combine(function(merged) { | ||
result.push(merged()); | ||
}); | ||
}, [merged]); | ||
s1(12)(2); s2(4)(44); s1(1); s2(12)(2); | ||
@@ -468,2 +485,27 @@ assert.deepEqual(result, [12, 2, 4, 44, 1, 12, 2]); | ||
}); | ||
it('should pass defined undefined along', function(){ | ||
var s1 = stream(); | ||
var s2 = stream(undefined); | ||
var merged = flyd.merge(s1, s2); | ||
assert.equal(merged(), undefined); | ||
s1(25); | ||
assert.equal(merged(), 25); | ||
s1(undefined); | ||
assert.equal(merged(), undefined); | ||
s2(15); | ||
assert.equal(merged(), 15); | ||
}); | ||
it('should work for s1 being defined first', function(){ | ||
var s1 = stream(undefined); | ||
var s2 = stream(); | ||
var merged = flyd.merge(s1, s2); | ||
assert.equal(merged(), undefined); | ||
s1(25); | ||
assert.equal(merged(), 25); | ||
}); | ||
it('ends only when both merged streams have ended', function() { | ||
@@ -484,2 +526,3 @@ var result = []; | ||
}); | ||
describe('ap', function() { | ||
@@ -543,2 +586,3 @@ it('applies functions in stream', function() { | ||
}); | ||
describe('of', function() { | ||
@@ -571,5 +615,5 @@ it('returns a stream with the passed value', function() { | ||
var one = flyd.stream(); | ||
stream([one], function(self) { | ||
self(flyd.stream([], function() { })); | ||
}); | ||
combine(function(one, self) { | ||
self(flyd.combine(function() { }, [])); | ||
}, [one]); | ||
one(1); | ||
@@ -579,5 +623,5 @@ }); | ||
var one = flyd.stream(); | ||
stream([one], function(self) { | ||
self(flyd.immediate(flyd.stream([], function() { }))); | ||
}); | ||
combine(function(one, self) { | ||
self(flyd.immediate(flyd.combine(function() { }, []))); | ||
}, [one]); | ||
one(1); | ||
@@ -593,3 +637,3 @@ }); | ||
// create a stream, the first dependant on `str` should still be updated | ||
flyd.stream([], function(self) {}); | ||
flyd.combine(function() {}, []); | ||
}, str); | ||
@@ -602,2 +646,3 @@ str(1); | ||
}); | ||
describe('transducer.js transducer support', function() { | ||
@@ -609,3 +654,3 @@ it('creates new stream with map applied', function() { | ||
var s2 = flyd.transduce(tx, s1); | ||
stream([s2], function() { result.push(s2()); }); | ||
combine(function(s2) { result.push(s2()); }, [s2]); | ||
s1(1)(2)(4)(6); | ||
@@ -622,3 +667,3 @@ assert.deepEqual(result, [3, 6, 12, 18]); | ||
var s2 = flyd.transduce(tx, s1); | ||
stream([s2], function() { result.push(s2()); }); | ||
combine(function(s2) { result.push(s2()); }, [s2]); | ||
s1(1)(2)(3)(4); | ||
@@ -635,3 +680,3 @@ assert.deepEqual(result, [6, 12]); | ||
var s2 = flyd.transduce(tx, s1); | ||
stream([s2], function() { result.push(s2()); }); | ||
combine(function(s2) { result.push(s2()); }, [s2]); | ||
s1(1)(1)(2)(3)(3)(3)(4); | ||
@@ -648,3 +693,3 @@ assert.deepEqual(result, [2, 4, 6, 8]); | ||
var s2 = flyd.transduce(tx, s1); | ||
stream([s2], function() { result.push(s2()); }); | ||
combine(function(s2) { result.push(s2()); }, [s2]); | ||
s1(1)(2); | ||
@@ -658,2 +703,3 @@ assert.notEqual(true, s2.end()); | ||
}); | ||
describe('Ramda transducer support', function() { | ||
@@ -665,3 +711,3 @@ it('creates new stream with map applied', function() { | ||
var s2 = flyd.transduce(tx, s1); | ||
stream([s2], function() { result.push(s2()); }); | ||
combine(function(s2) { result.push(s2()); }, [s2]); | ||
s1(1)(2)(4)(6); | ||
@@ -678,3 +724,3 @@ assert.deepEqual(result, [3, 6, 12, 18]); | ||
var s2 = flyd.transduce(tx, s1); | ||
stream([s2], function() { result.push(s2()); }); | ||
combine(function(s2) { result.push(s2()); }, [s2]); | ||
s1(1)(2)(3)(4); | ||
@@ -699,7 +745,9 @@ assert.deepEqual(result, [6, 12]); | ||
var s2 = flyd.transduce(tx, s1); | ||
stream([s2], function() { result.push(s2()); }); | ||
combine(function(s2) { result.push(s2()); }, [s2]); | ||
s1(1)(1)(2)(3)(3)(3)(4); | ||
assert.deepEqual(result, [2, 4, 6, 8]); | ||
}); | ||
// @todo: Better transducer tests!! | ||
}); | ||
describe('atomic updates', function() { | ||
@@ -709,7 +757,7 @@ it('does atomic updates', function() { | ||
var a = stream(1); | ||
var b = stream([a], function() { return a() * 2; }); | ||
var c = stream([a], function() { return a() + 4; }); | ||
var d = stream([b, c], function(self, ch) { | ||
var b = combine(doubleFn, [a]); | ||
var c = combine(function(a) { return a() + 4; }, [a]); | ||
var d = combine(function(b, c) { | ||
result.push(b() + c()); | ||
}); | ||
}, [b, c]); | ||
a(2); | ||
@@ -721,5 +769,5 @@ assert.deepEqual(result, [7, 10]); | ||
var s1 = stream(1); | ||
var s1x2 = flyd.map(function(n) { return n*2; }, s1); | ||
var s2 = stream([s1, s1x2], function() { return s1() + s1x2(); }); | ||
var s1x4 = stream([s1, s2], function() { return s1() + s2(); }); | ||
var s1x2 = flyd.map(function(x) { return x * 2; }, s1); | ||
var s2 = combine(sumFn, [s1, s1x2]); | ||
var s1x4 = combine(sumFn, [s1, s2]); | ||
flyd.map(function(n) { result.push(n); }, s1x4); | ||
@@ -732,8 +780,8 @@ s1(2)(3)(4); | ||
var a = flyd.stream(); | ||
var b = flyd.stream([a], function bs() { return a() + 1; }); | ||
var c = flyd.stream([a], function cs() { return a() + 2; }); | ||
var d = flyd.stream([c], function ds() { return c() + 3; }); | ||
var e = flyd.stream([b, d], function res(){ | ||
var b = flyd.combine(function(a) { return a() + 1; }, [a]); | ||
var c = flyd.combine(function(a) { return a() + 2; }, [a]); | ||
var d = flyd.combine(function(c) { return c() + 3; }, [c]); | ||
var e = flyd.combine(function(b, d){ | ||
return b() + d(); | ||
}); | ||
}, [b, d]); | ||
flyd.map(function(v) { result.push(v); }, e); | ||
@@ -746,6 +794,6 @@ a(1)(5)(11); | ||
var a = flyd.stream(); | ||
var b = flyd.stream([a], function() { return a() + 1; }); | ||
var c = flyd.stream([a], function() { return a() + 2; }); | ||
var d = flyd.stream([a], function() { return a() + 4; }); | ||
var e = flyd.stream([b, c, d], function() { return b() + c() + d(); }); | ||
var b = flyd.combine(function(a) { return a() + 1; }, [a]); | ||
var c = flyd.combine(function(a) { return a() + 2; }, [a]); | ||
var d = flyd.combine(function(a) { return a() + 4; }, [a]); | ||
var e = flyd.combine(function(b, c, d) { return b() + c() + d(); }, [b, c, d]); | ||
flyd.map(function(v) { result.push(v); }, e); | ||
@@ -758,15 +806,15 @@ a(1)(2)(3); | ||
var a = flyd.stream(0); | ||
var b = flyd.stream([a], function() { return a() + 1; }); | ||
var c = flyd.stream([a], function() { return a() + 2; }); | ||
var b = flyd.combine(function(a) { return a() + 1; }, [a]); | ||
var c = flyd.combine(function(a) { return a() + 2; }, [a]); | ||
var d = flyd.stream(0); | ||
var e = flyd.stream([d], function() { return d() + 4; }); | ||
var f = flyd.stream([d], function() { return d() + 5; }); | ||
var g = flyd.stream([d], function() { return d() + 6; }); | ||
var e = flyd.combine(function(d) { return d() + 4; }, [d]); | ||
var f = flyd.combine(function(d) { return d() + 5; }, [d]); | ||
var g = flyd.combine(function(d) { return d() + 6; }, [d]); | ||
var h = flyd.stream([a, b, c, d, e, f, g], function(self, changed) { | ||
var h = flyd.combine(function(a,b,c,d,e,f,g,self,changed) { | ||
var vals = changed.map(function(s) { return s(); }); | ||
result.push(vals); | ||
return 1; | ||
}); | ||
}, [a, b, c, d, e, f, g]); | ||
a(1); d(2); a(3); | ||
@@ -773,0 +821,0 @@ assert.deepEqual(result, [ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
321781
701
8453