Skip to content
This repository has been archived by the owner on Sep 10, 2022. It is now read-only.

Commit

Permalink
Remove global observable and use Symbol.observable instead
Browse files Browse the repository at this point in the history
  • Loading branch information
acdlite committed Jun 12, 2016
1 parent 534415d commit fbb62b6
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 30 deletions.
2 changes: 0 additions & 2 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -633,8 +633,6 @@ Augments a higher-order component so that when used, it copies static properties

## Observable utilities

**The functions in this section require an Observable polyfill, such as RxJS 5. `Observable` must be available globally.**

It turns out that much of the React Component API can be expressed in terms of observables:

- Instead of `setState()`, combine multiple streams together.
Expand Down
11 changes: 4 additions & 7 deletions src/packages/recompose/__tests__/createEventHandler-test.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import test from 'ava'
import { createEventHandler } from '../'

import { Observable } from 'rxjs/Observable'
global.Observable = Observable

test('createEventHandler creates a subject that broadcasts new values when called as a function', t => {
test('createEventHandler creates an event handler and a corresponding stream', t => {
const result = []
const { stream, handler } = createEventHandler()
const subscription = stream.subscribe(v => result.push(v))
const subscription = stream.subscribe({ next: v => result.push(v) })

handler(1)
handler(2)
Expand All @@ -21,8 +18,8 @@ test('handles multiple subscribers', t => {
const result1 = []
const result2 = []
const { handler, stream } = createEventHandler()
const subscription1 = stream.subscribe(v => result1.push(v))
const subscription2 = stream.subscribe(v => result2.push(v))
const subscription1 = stream.subscribe({ next: v => result1.push(v) })
const subscription2 = stream.subscribe({ next: v => result2.push(v) })

handler(1)
handler(2)
Expand Down
19 changes: 14 additions & 5 deletions src/packages/recompose/__tests__/mapPropsStream-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,29 @@ import { startWith } from 'rxjs/operator/startWith'
import { scan } from 'rxjs/operator/scan'
import { _do } from 'rxjs/operator/do'
import { map } from 'rxjs/operator/map'
import { Observable } from 'rxjs'
import {
withState,
compose,
branch,
mapPropsStream,
createEventHandler
mapPropsStream as _mapPropsStream,
createEventHandler as _createEventHandler
} from '../'
import { mount, shallow } from 'enzyme'

import { Observable } from 'rxjs/Observable'
global.Observable = Observable

const identity = t => t

const mapPropsStream = transform =>
_mapPropsStream(props$ => transform(Observable.from(props$)))

const createEventHandler = () => {
const { stream, handler } = _createEventHandler()
return {
handler,
stream: Observable.from(stream)
}
}

test('mapPropsStream maps a stream of owner props to a stream of child props', t => {
const SmartButton = mapPropsStream(props$ => {
const { handler: onClick, stream: increment$ } = createEventHandler()
Expand Down
22 changes: 15 additions & 7 deletions src/packages/recompose/componentFromStream.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Component } from 'react'
import { createChangeEmitter } from 'change-emitter'
import $$observable from 'symbol-observable'

const componentFromStream = propsToVdom =>
class ComponentFromStream extends Component {
Expand All @@ -8,9 +9,17 @@ const componentFromStream = propsToVdom =>
propsEmitter = createChangeEmitter();

// Stream of props
props$ = new Observable(observer =>
this.propsEmitter.listen(props => observer.next(props))
);
props$ = {
subscribe: observer => {
const unsubscribe = this.propsEmitter.listen(
props => observer.next(props)
)
return { unsubscribe }
},
[$$observable]() {
return this
}
};

// Stream of vdom
vdom$ = propsToVdom(this.props$);
Expand All @@ -22,17 +31,16 @@ const componentFromStream = propsToVdom =>

componentWillMount() {
// Subscribe to child prop changes so we know when to re-render
this.subscription = this.vdom$.subscribe(
vdom => {
this.subscription = this.vdom$.subscribe({
next: vdom => {
this.didReceiveVdom = true
if (!this.componentHasMounted) {
this.state = { vdom }
} else {
this.setState({ vdom })
}
}
)

})
this.propsEmitter.emit(this.props)
}

Expand Down
13 changes: 10 additions & 3 deletions src/packages/recompose/createEventHandler.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import $$observable from 'symbol-observable'
import { createChangeEmitter } from 'change-emitter'

const createEventHandler = () => {
const emitter = createChangeEmitter()
const stream = new Observable(observer =>
emitter.listen(value => observer.next(value))
)
const stream = {
subscribe(observer) {
const unsubscribe = emitter.listen(value => observer.next(value))
return { unsubscribe }
},
[$$observable]() {
return this
}
}
return {
handler: emitter.emit,
stream
Expand Down
16 changes: 11 additions & 5 deletions src/packages/recompose/mapPropsStream.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import $$observable from 'symbol-observable'
import createEagerFactory from './createEagerFactory'
import createHelper from './createHelper'
import componentFromStream from './componentFromStream'

const mapPropsStream = transform => BaseComponent => {
const factory = createEagerFactory(BaseComponent)
return componentFromStream(ownerProps$ =>
new Observable(observer => {
return componentFromStream(ownerProps$ => ({
subscribe(observer) {
const subscription = transform(ownerProps$).subscribe({
next: childProps => observer.next(factory(childProps))
})
return () => subscription.unsubscribe()
})
)
return {
unsubscribe: () => subscription.unsubscribe()
}
},
[$$observable]() {
return this
}
}))
}

export default createHelper(mapPropsStream, 'mapPropsStream')
3 changes: 2 additions & 1 deletion src/packages/recompose/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"dependencies": {
"change-emitter": "^0.1.2",
"fbjs": "^0.8.1",
"hoist-non-react-statics": "^1.0.0"
"hoist-non-react-statics": "^1.0.0",
"symbol-observable": "^0.2.4"
},
"peerDependencies": {
"react": "^0.14.0 || ^15.0.0"
Expand Down

0 comments on commit fbb62b6

Please sign in to comment.