UNPKG

flyd

Version:

The less is more, modular, functional reactive programming library

527 lines (466 loc) 14.6 kB
(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'); 'use strict'; function isFunction(obj) { return !!(obj && obj.constructor && obj.call && obj.apply); } // Globals var toUpdate = []; var inStream; // Library functions use self callback to accept (null, undefined) update triggers. function map(f, s) { return combine(function(s, self) { self(f(s.val)); }, [s]); } function on(f, s) { return combine(function(s) { f(s.val); }, [s]); } function boundMap(f) { return map(f, this); } var scan = curryN(3, function(f, acc, s) { var ns = combine(function(s, self) { self(acc = f(acc, s.val)); }, [s]); if (!ns.hasVal) ns(acc); return ns; }); var merge = curryN(2, function(s1, s2) { 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; }, [s1.end, s2.end]), s); return s; }); function ap(s2) { var s1 = this; return combine(function(s1, s2, self) { self(s1.val(s2.val)); }, [s1, s2]); } function initialDepsNotMet(stream) { stream.depsMet = stream.deps.every(function(s) { return s.hasVal; }); return !stream.depsMet; } function updateStream(s) { if ((s.depsMet !== true && initialDepsNotMet(s)) || (s.end !== undefined && s.end.val === true)) return; if (inStream !== undefined) { toUpdate.push(s); return; } inStream = s; if (s.depsChanged) s.fnArgs[s.fnArgs.length - 1] = s.depsChanged; var returnVal = s.fn.apply(s.fn, s.fnArgs); if (returnVal !== undefined) { s(returnVal); } inStream = undefined; if (s.depsChanged !== undefined) s.depsChanged = []; s.shouldUpdate = false; if (flushing === false) flushUpdate(); } var order = []; var orderNextIdx = -1; function findDeps(s) { var i, listeners = s.listeners; if (s.queued === false) { s.queued = true; for (i = 0; i < listeners.length; ++i) { findDeps(listeners[i]); } order[++orderNextIdx] = s; } } function updateDeps(s) { var i, o, list, listeners = s.listeners; for (i = 0; i < listeners.length; ++i) { list = listeners[i]; if (list.end === s) { endStream(list); } else { if (list.depsChanged !== undefined) list.depsChanged.push(s); list.shouldUpdate = true; findDeps(list); } } for (; orderNextIdx >= 0; --orderNextIdx) { o = order[orderNextIdx]; if (o.shouldUpdate === true) updateStream(o); o.queued = false; } } var flushing = false; function flushUpdate() { flushing = true; while (toUpdate.length > 0) { var s = toUpdate.shift(); if (s.vals.length > 0) s.val = s.vals.shift(); updateDeps(s); } flushing = false; } function isStream(stream) { return isFunction(stream) && 'hasVal' in stream; } function streamToString() { return 'stream(' + this.val + ')'; } function updateStreamValue(s, n) { if (n !== undefined && n !== null && isFunction(n.then)) { n.then(s); return; } s.val = n; s.hasVal = true; if (inStream === undefined) { flushing = true; updateDeps(s); if (toUpdate.length > 0) flushUpdate(); else flushing = false; } else if (inStream === s) { markListeners(s, s.listeners); } else { s.vals.push(n); toUpdate.push(s); } } function markListeners(s, lists) { var i, list; for (i = 0; i < lists.length; ++i) { list = lists[i]; if (list.end !== s) { if (list.depsChanged !== undefined) { list.depsChanged.push(s); } list.shouldUpdate = true; } else { endStream(list); } } } function createStream() { function s(n) { return arguments.length > 0 ? (updateStreamValue(s, n), s) : s.val; } s.hasVal = false; s.val = undefined; s.vals = []; s.listeners = []; s.queued = false; s.end = undefined; s.map = boundMap; s.ap = ap; s.of = stream; s.toString = streamToString; return s; } function addListeners(deps, s) { for (var i = 0; i < deps.length; ++i) { deps[i].listeners.push(s); } } function createDependentStream(deps, fn) { var s = createStream(); s.fn = fn; s.deps = deps; s.depsMet = false; s.depsChanged = deps.length > 0 ? [] : undefined; s.shouldUpdate = false; addListeners(deps, s); return s; } function immediate(s) { if (s.depsMet === false) { s.depsMet = true; updateStream(s); } return s; } function removeListener(s, listeners) { var idx = listeners.indexOf(s); listeners[idx] = listeners[listeners.length - 1]; listeners.length--; } function detachDeps(s) { for (var i = 0; i < s.deps.length; ++i) { removeListener(s, s.deps[i].listeners); } s.deps.length = 0; } function endStream(s) { if (s.deps !== undefined) detachDeps(s); if (s.end !== undefined) detachDeps(s.end); } function endsOn(endS, s) { detachDeps(s.end); endS.listeners.push(s.end); s.end.deps.push(endS); return s; } function trueFn() { return true; } 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); 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.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; } var transduce = curryN(2, function(xform, source) { xform = xform(new StreamTransformer()); return combine(function(source, self) { var res = xform['@@transducer/step'](undefined, source.val); if (res && res['@@transducer/reduced'] === true) { self.end(true); return res['@@transducer/value']; } else { return res; } }, [source]); }); function StreamTransformer() { } StreamTransformer.prototype['@@transducer/init'] = function() { }; StreamTransformer.prototype['@@transducer/result'] = function() { }; StreamTransformer.prototype['@@transducer/step'] = function(s, v) { return v; }; module.exports = { stream: stream, combine: curryN(2, combine), isStream: isStream, transduce: transduce, merge: merge, scan: scan, endsOn: endsOn, map: curryN(2, map), on: curryN(2, on), curryN: curryN, immediate: immediate, }; },{"ramda/src/curryN":4}],2:[function(require,module,exports){ var flyd = require('../../lib'); module.exports = function(f, s) { return flyd.combine(function(s, own) { flyd.map(own, f(s())); }, [s]); }; },{"../../lib":1}],3:[function(require,module,exports){ var flyd = require('../../lib'); module.exports = function(src, term) { return flyd.endsOn(flyd.merge(term, src.end), flyd.combine(function(src, self) { self(src()); }, [src])); }; },{"../../lib":1}],4:[function(require,module,exports){ var _arity = require('./internal/_arity'); var _curry1 = require('./internal/_curry1'); var _curry2 = require('./internal/_curry2'); var _curryN = require('./internal/_curryN'); /** * Returns a curried equivalent of the provided function, with the * specified arity. The curried function has two unusual capabilities. * First, its arguments needn't be provided one at a time. If `g` is * `R.curryN(3, f)`, the following are equivalent: * * - `g(1)(2)(3)` * - `g(1)(2, 3)` * - `g(1, 2)(3)` * - `g(1, 2, 3)` * * Secondly, the special placeholder value `R.__` may be used to specify * "gaps", allowing partial application of any combination of arguments, * regardless of their positions. If `g` is as above 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)(_, 3)(1)` * * @func * @memberOf R * @category Function * @sig Number -> (* -> a) -> (* -> a) * @param {Number} length The arity for the returned function. * @param {Function} fn The function to curry. * @return {Function} A new, curried function. * @see R.curry * @example * * var addFourNumbers = function() { * return R.sum([].slice.call(arguments, 0, 4)); * }; * * var curriedAddFourNumbers = R.curryN(4, addFourNumbers); * var f = curriedAddFourNumbers(1, 2); * var g = f(3); * g(4); //=> 10 */ module.exports = _curry2(function curryN(length, fn) { if (length === 1) { return _curry1(fn); } return _arity(length, _curryN(length, [], fn)); }); },{"./internal/_arity":5,"./internal/_curry1":6,"./internal/_curry2":7,"./internal/_curryN":8}],5:[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'); } }; },{}],6:[function(require,module,exports){ /** * Optimized internal two-arity curry function. * * @private * @category Function * @param {Function} fn The function to curry. * @return {Function} The curried function. */ module.exports = function _curry1(fn) { return function f1(a) { if (arguments.length === 0) { return f1; } else if (a != null && a['@@functional/placeholder'] === true) { return f1; } else { return fn.apply(this, arguments); } }; }; },{}],7:[function(require,module,exports){ var _curry1 = require('./_curry1'); /** * Optimized internal two-arity curry function. * * @private * @category Function * @param {Function} fn The function to curry. * @return {Function} The curried function. */ module.exports = function _curry2(fn) { return function f2(a, b) { var n = arguments.length; if (n === 0) { return f2; } 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 != null && a['@@functional/placeholder'] === true && b != null && b['@@functional/placeholder'] === true) { return f2; } else if (n === 2 && a != null && a['@@functional/placeholder'] === true) { return _curry1(function(a) { return fn(a, b); }); } else if (n === 2 && b != null && b['@@functional/placeholder'] === true) { return _curry1(function(b) { return fn(a, b); }); } else { return fn(a, b); } }; }; },{"./_curry1":6}],8:[function(require,module,exports){ var _arity = require('./_arity'); /** * Internal curryN function. * * @private * @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 _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; } 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)); }; }; },{"./_arity":5}],9:[function(require,module,exports){ var flyd = require('flyd'); var flatMap = require('flyd/module/flatmap'); var takeUntil = require('flyd/module/takeuntil'); document.addEventListener('DOMContentLoaded', function() { var dragElm = document.getElementById('drag'); var mousedown = flyd.stream(); var mousemove = flyd.stream(); var mouseup = flyd.stream(); dragElm.addEventListener('mousedown', mousedown); document.addEventListener('mousemove', mousemove); document.addEventListener('mouseup', mouseup); var mousedrag = flatMap(function(md) { var startX = md.offsetX, startY = md.offsetY; return takeUntil(flyd.map(function(mm) { mm.preventDefault(); return { left: mm.clientX - startX, top: mm.clientY - startY }; }, mousemove), mouseup); }, mousedown); flyd.on(function(pos) { dragElm.style.top = pos.top + 'px'; dragElm.style.left = pos.left + 'px'; }, mousedrag); }); },{"flyd":1,"flyd/module/flatmap":2,"flyd/module/takeuntil":3}]},{},[9]);