From d3c0dc723b3745c202b4d2831f315f973dc08479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Einar=20Nor=C3=B0fj=C3=B6r=C3=B0?= Date: Thu, 1 Feb 2018 21:08:41 +0000 Subject: [PATCH 1/3] remove promise swallowing --- README.md | 1 + lib/index.js | 7 ---- test/index.js | 98 +++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 80 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 8e2023c..91ca9f2 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ __Other features__ * Supports the transducer protocol. You can for instance transduce streams with [Ramda](http://ramdajs.com/) and [transducers.js](https://github.com/jlongster/transducers.js). +* Conforms to the fantasy land [monad](https://github.com/fantasyland/fantasy-land#monad) specification * [Atomic updates](#atomic-updates). ## Examples diff --git a/lib/index.js b/lib/index.js index 7a500f8..17e84de 100644 --- a/lib/index.js +++ b/lib/index.js @@ -438,7 +438,6 @@ flyd.fromPromise = function fromPromise(p) { return s; } -/* istanbul ignore next */ flyd.flattenPromise = function flattenPromise(s) { return combine(function(s, self) { s().then(self); @@ -676,12 +675,6 @@ function flushUpdate() { * @param {*} value */ function updateStreamValue(s, n) { - /* istanbul ignore if */ - if (n !== undefined && n !== null && isFunction(n.then)) { - console.warn('flyd: Promise swallowing has been deprecated, please see https://github.com/paldepind/flyd#promises for more info'); - n.then(s); - return; - } s.val = n; s.hasVal = true; if (inStream === undefined) { diff --git a/test/index.js b/test/index.js index 8e79ad5..08b6385 100644 --- a/test/index.js +++ b/test/index.js @@ -369,26 +369,86 @@ describe('stream', function() { }); }); - describe('promise swallowing', function() { - it('pushes result of promise down the stream', function(done) { - var s = flyd.fromPromise(Promise.resolve(12)); - combine(function(s) { - assert.equal(s(), 12); - done(); - }, [s]); + describe('Promises', function() { + describe('fromPromise', function() { + it('pushes result of promise down the stream', function(done) { + var s = flyd.fromPromise(Promise.resolve(12)); + combine(function(s) { + assert.equal(s(), 12); + done(); + }, [s]); + }); + it('recursively unpacks promise', function(done) { + var s = flyd.fromPromise(new Promise(function(res) { + setTimeout(function() { + res(new Promise(function(res) { + setTimeout(res.bind(null, 12)); + })); + }, 20); + })); + combine(function(s) { + assert.equal(s(), 12); + done(); + }, [s]); + }); + + it('does not process out of order promises', function(done) { + var promises = []; + var delay = function(ms, val) { + var p = new Promise(function(res) { + setTimeout(function() { + res(val); + }, ms) + }); + promises.push(p); + return p; + }; + + var s = stream(); + var res = s.chain(function(val) { + return flyd.fromPromise(delay(val, val)); + }) + .pipe(flyd.scan(function(acc, v) { + return acc + v; + }, 0)); + s(100)(50)(70)(200); + + Promise.all(promises).then(function() { + assert.equal(res(), 200); + done(); + }); + + }); }); - it('recursively unpacks promise', function(done) { - var s = flyd.fromPromise(new Promise(function(res) { - setTimeout(function() { - res(new Promise(function(res) { - setTimeout(res.bind(null, 12)); - })); - }, 20); - })); - combine(function(s) { - assert.equal(s(), 12); - done(); - }, [s]); + describe('flattenPromise', function() { + it('processes out of order promises', function(done) { + var promises = []; + var delay = function(ms, val) { + var p = new Promise(function(res) { + setTimeout(function() { + res(val); + }, ms) + }); + promises.push(p); + return p; + }; + + var s = stream(); + var res = s.map(function(val) { + return delay(val, val); + }) + .pipe(flyd.flattenPromise) + .pipe(flyd.scan(function(acc, v) { + return acc + v; + }, 0)); + s(100)(50)(70)(200); + + Promise.all(promises).then(function() { + assert.equal(res(), 420); + done(); + }); + + }); }); }); From 11513ae87908fc4a8ebd45acb20de264ae4990c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Einar=20Nor=C3=B0fj=C3=B6r=C3=B0?= Date: Mon, 12 Feb 2018 23:48:26 +0000 Subject: [PATCH 2/3] remove deprecation notices from stream.map and stream.ap --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 91ca9f2..020405c 100644 --- a/README.md +++ b/README.md @@ -648,7 +648,7 @@ var evenNumbers = numbers .pipe(filter(isEven)); ``` -### stream.map(f) __Deprecated__ +### stream.map(f) Returns a new stream identical to the original except every value will be passed through `f`. @@ -667,7 +667,7 @@ var numbers = flyd.stream(0); var squaredNumbers = numbers.map(function(n) { return n*n; }); ``` -### stream1.ap(stream2) __Deprecated__ +### stream1.ap(stream2) `stream1` must be a stream of functions. From f3a899be7ba13f3d8b3be02d2cebd43a85e24ffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Einar=20Nor=C3=B0fj=C3=B6r=C3=B0?= Date: Mon, 12 Feb 2018 23:48:50 +0000 Subject: [PATCH 3/3] remove flatMap since it is replaced by flyd.chain --- examples/drag-and-drop/script.js | 3 +- index.d.ts | 10 ------ module/flatmap/README.md | 54 -------------------------------- module/flatmap/index.js | 23 -------------- 4 files changed, 1 insertion(+), 89 deletions(-) delete mode 100644 module/flatmap/README.md delete mode 100644 module/flatmap/index.js diff --git a/examples/drag-and-drop/script.js b/examples/drag-and-drop/script.js index 16c8316..1c2db59 100644 --- a/examples/drag-and-drop/script.js +++ b/examples/drag-and-drop/script.js @@ -1,5 +1,4 @@ var flyd = require('flyd'); -var flatMap = require('flyd/module/flatmap'); var takeUntil = require('flyd/module/takeuntil'); document.addEventListener('DOMContentLoaded', function() { @@ -13,7 +12,7 @@ document.addEventListener('DOMContentLoaded', function() { document.addEventListener('mousemove', mousemove); document.addEventListener('mouseup', mouseup); - var mousedrag = flatMap(function(md) { + var mousedrag = flyd.chain(function(md) { var startX = md.offsetX, startY = md.offsetY; return takeUntil(flyd.map(function(mm) { diff --git a/index.d.ts b/index.d.ts index e959adf..f2b7d0b 100644 --- a/index.d.ts +++ b/index.d.ts @@ -128,16 +128,6 @@ declare module 'flyd/module/filter' { export = _Filter; } -declare module 'flyd/module/flatmap' { - type projection = (val: T) => flyd.Stream; - interface flatMap { - (project: projection, source: flyd.Stream): flyd.Stream; - (project: projection): (source: flyd.Stream) => flyd.Stream; - } - const _flatMap: flatMap; - export = _flatMap; -} - declare module 'flyd/module/forwardto' { interface ForwardTo { (stream: flyd.Stream, project: (value: V) => T): flyd.Stream; diff --git a/module/flatmap/README.md b/module/flatmap/README.md deleted file mode 100644 index ea18b69..0000000 --- a/module/flatmap/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# flyd-flatmap - -Flatten a stream of streams into a single stream of values. This is useful for -composing nested streams together to get a single stream of the final result -values. - -__Graph__ - -``` -a: {---.------.----} - {a-b} {a-b} -flatMap(a): {---a-b----a-b--} -``` - -__Signature__ - -`(a -> Stream b) -> Stream a -> Stream b` - -__Usage__ - -```js -const flatMap = require('flyd/module/flatmap') -const request = require('flyd-ajax') - -// Form submit events -const submit = flyd.stream() -// Every time the form is submitted, we make an ajax request -// We get a flattened stream of the ajax responses -const responses = flatMap( - ()=> request({method: 'get', url: 'http://spacejam.com'}).load -, submit) - -submit(true) -flyd.map(resp => console.log(resp), responses) -// {body: "SpaceJam...", status: 200, ...} - - -const R = require('ramda') -const click$ = flyd.stream() - -// Once a user makes a click, we want to make three different ajax requests. -// But, each ajax request must happen in sequence, and we want a stream of the final result value -const response$ = R.compose( - flatMap(requestStream3) -, flatMap(requestStream2) -, flatMap(requestStream1) -)(click$) -// response$ will be a stream of final ajax responses from requestStream3 -// requestStream1 will trigger on every click -// requestStream2 will trigger when requestStream1 is completed -// requestStream3 will trigger when requestStream2 is completed -// finally, response$ will have all the values of the result of requestStream3 -``` - diff --git a/module/flatmap/index.js b/module/flatmap/index.js deleted file mode 100644 index d704749..0000000 --- a/module/flatmap/index.js +++ /dev/null @@ -1,23 +0,0 @@ -var flyd = require('../../lib'); - -console.warn('flyd/module/flatmap has been deprecated in favour of flyd.chain'); - -/** - * Given a stream of streams, returns a single stream of merged values - * from the created streams. - * - * Ends when every created stream and the main stream ends. - * - * @name flyd.flatMap - * @param {Function} f - Stream producing function `(x) -> stream.` - * @param {stream.} s - Stream to flat map values through f - * @return {stream.} - Resulting flat mapped stream - * - * @example - * var s = flyd.stream(); - * var fn = (x) => flyd.stream(x); - * var flat = flyd.flatMap(fn, s); - * s(0)(1)(2); - * // flat = 0, 1, 2 - */ -module.exports = flyd.chain;