Skip to content

Commit

Permalink
Change from factory to provider, like react-redux
Browse files Browse the repository at this point in the history
Also borrowed some code from them, hehe
  • Loading branch information
dralletje committed Oct 18, 2015
1 parent 33d9bfe commit f6a05eb
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 15 deletions.
5 changes: 4 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
module.exports = require('./build/exothermic')
module.exports = {
connect: require('./build/connect'),
Provider: require('./build/Provider'),
}
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
"eslint-plugin-react": "^3.5.1",
"eslint": "^1.7.1"
},
"peerDependencies": {
"react": "^0.14.0"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "./node_modules/.bin/babel --stage 0 source -d build",
Expand Down
27 changes: 27 additions & 0 deletions source/Provider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import {Component, PropTypes, Children} from 'react';
import firebaseShape from './firebaseShape'

export default class Provider extends Component {
static propTypes = {
firebase: firebaseShape.isRequired,
children: PropTypes.element.isRequired,
}

static childContextTypes = {
firebase: firebaseShape.isRequired,
}

getChildContext() {
return {firebase: this.firebase};
}

constructor(props, context) {
super(props, context);
this.firebase = props.firebase;
}

render() {
const {children} = this.props;
return Children.only(children);
}
}
42 changes: 28 additions & 14 deletions source/exothermic.js → source/connect.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react'
import firebaseShape from './firebaseShape'

/*************/
/* HELPERS */
Expand Down Expand Up @@ -39,6 +40,12 @@ const massUnbind = (keys, listeners) => {
keys.forEach(key => listeners[key]())
}

const ensureCallable = maybeFn =>
typeof maybeFn === 'function' ? maybeFn : (_ => maybeFn)

const getDisplayName = WrappedComponent =>
WrappedComponent.displayName || WrappedComponent.name || 'Component';

/***************/
/* COMPONENT */
/***************/
Expand All @@ -47,28 +54,34 @@ const massUnbind = (keys, listeners) => {
const initial = Symbol('Initial value')


export default baseref => dataOrFn => Component => {
const linkFn = typeof dataOrFn === 'function' ? dataOrFn : (_ => dataOrFn)
export default (dataOrFn = {}) => WrappedComponent => {
const linkFn = ensureCallable(dataOrFn)

const getPaths = props =>
props.endothermicLoaded === false
? {}
: linkFn(props)

const listen = update => (path, key) =>
onValue(baseref.child(path), value => {
update(key, value)
})

return class Endothermic extends React.Component {
static displayName = `Endothermic(${Component.displayName || Component.name})`
static displayName = `Endothermic(${getDisplayName(WrappedComponent)})`
static WrappedComponent = WrappedComponent
static contextTypes = {
firebase: firebaseShape,
}
static propTypes = {
firebase: firebaseShape,
}

constructor(props) {
super(props)
constructor(props, context) {
super(props, context)

this.firebase = props.firebase || context.firebase;

this.listen = (path, key) =>
onValue(this.firebase.child(path), value => {
this.setState({ [key]: value })
})

this.listen = listen( (key, value) => {
this.setState({ [key]: value })
})
this.listeners = {}
this.paths = getPaths(this.props)
this.state = mapObject(this.paths, _ => initial)
Expand Down Expand Up @@ -118,9 +131,10 @@ export default baseref => dataOrFn => Component => {
.every( ([key, value]) => value !== initial)

return (
<Component
<WrappedComponent
{...this.props}
{...this.state}
firebase={this.firebase}
endothermicLoaded={loaded}
/>
)
Expand Down
7 changes: 7 additions & 0 deletions source/firebaseShape.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {PropTypes} from 'react';

export default PropTypes.shape({
child: PropTypes.func.isRequired,
on: PropTypes.func.isRequired,
off: PropTypes.func.isRequired,
});

0 comments on commit f6a05eb

Please sign in to comment.