Skip to content

Commit

Permalink
feat(thru): Make thru parametric in its return type (#473)
Browse files Browse the repository at this point in the history
  • Loading branch information
briancavalier committed Aug 11, 2017
1 parent d3889d3 commit b9dc0e2
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 16 deletions.
23 changes: 21 additions & 2 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1022,14 +1022,16 @@ stream.loop((values, x) => {

### thru

#### `stream.thru(transform) -> Stream`
#### `stream.thru(transform) -> R`

`transform(stream: Stream) -> Stream`
`transform (stream: Stream<A>) -> R`

Use a functional API in fluent style.

Functional APIs allow for the highest degree of modularity via external packages, such as [`@most/hold`](https://github.com/mostjs/hold), *without the risks of modifying prototypes*.

Note that the `transform` function may return any type (not just a Stream), and `.thru(transform)` will also return that type.

If you prefer using fluent APIs, `thru` allows using those functional APIs in a fluent style. For example:

```es6
Expand All @@ -1055,6 +1057,23 @@ hold(periodic(10, 1)
.observe(x => console.log(x))
```

Note also that the function passed to `thru` is not restricted to returning a stream. For example:

```es6
import { from } from 'most'

const lastAsPromise = (stream) =>
stream.reduce((_, x) => x)

// since lastAsPromise returns a Promise
// stream.thru(lastAsPromise) *also* returns a Promise because

// logs 3
from([1, 2, 3])
.thru(lastAsPromise) // returns a Promise
.then(x => console.log(x))
```

#### Multiple arguments

Multiple arguments should be handled via partial application of the function passed to thru, using `bind` or a currying or partial application utility from your favorite functional programming library.
Expand Down
2 changes: 1 addition & 1 deletion src/combinator/thru.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/** @license MIT License (c) copyright 2010-2016 original author or authors */
/** @license MIT License (c) copyright 2010-2017 original author or authors */
/** @author Brian Cavalier */
/** @author John Hann */

Expand Down
22 changes: 10 additions & 12 deletions test/combinator/thru-test.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,28 @@
/* global describe, it */
require('buster').spec.expose()
var expect = require('buster').expect
import { spec, referee } from 'buster'
const { describe, it } = spec
const { assert } = referee

var thru = require('../../src/combinator/thru').thru
import { thru } from '../../src/combinator/thru'

describe('thru', function () {
it('should apply f to stream', function () {
var stream = {}
var expected = {}
function f (s) {
return expected
}
const stream = {}
const expected = {}
const f = s => expected

expect(thru(f, stream)).toBe(expected)
assert.same(expected, thru(f, stream))
})

it('should throw synchronously if f throws synchronously', function () {
var error = new Error()
const error = new Error()
function f () {
throw error
}

try {
thru(f, {})
} catch (e) {
expect(e).toBe(error)
assert.same(error, e)
}
})
})
2 changes: 1 addition & 1 deletion type-definitions/most.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ export interface Stream<A> extends Source<A> {
recoverWith<B>(p: (a: B) => Stream<A>): Stream<A>;
multicast(): Stream<A>;

thru<B>(transform: (stream: Stream<A>) => Stream<B>): Stream<B>;
thru<B>(transform: (stream: Stream<A>) => B): B;
}

declare interface DisposeFn {
Expand Down

0 comments on commit b9dc0e2

Please sign in to comment.