forked from prescottprue/redux-firebasev3
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconnect.js
107 lines (83 loc) · 2.68 KB
/
connect.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import React, { PropTypes, Component } from 'react'
import { watchEvents, unWatchEvents } from './actions/query'
const defaultEvent = {
path: '',
type: 'value'
}
const ensureCallable = maybeFn => //eslint-disable-line
typeof maybeFn === 'function' ? maybeFn : () => maybeFn //eslint-disable-line
const flatMap = arr => (arr && arr.length) ? arr.reduce((a, b) => a.concat(b)) : []
const createEvents = ({type, path}) => {
switch (type) {
case 'once':
return [{name: 'once', path}]
case 'value':
return [{name: 'value', path}]
case 'all':
return [
{name: 'first_child', path},
{name: 'child_added', path},
{name: 'child_removed', path},
{name: 'child_moved', path},
{name: 'child_changed', path}
]
default:
return []
}
}
const transformEvent = event => Object.assign({}, defaultEvent, event)
const getEventsFromDefinition = def => flatMap(def.map(path => {
if (typeof path === 'string' || path instanceof String) {
return createEvents(transformEvent({ path }))
}
if (typeof path === 'array' || path instanceof Array) { // eslint-disable-line
return createEvents(transformEvent({ type: 'all', path: path[0] }))
}
if (typeof path === 'object' || path instanceof Object) {
const type = path.type || 'value'
switch (type) {
case 'value':
return createEvents(transformEvent({ path: path.path }))
case 'once':
return createEvents(transformEvent({ type: 'once', path: path.path }))
case 'array':
return createEvents(transformEvent({ type: 'all', path: path.path }))
}
}
return []
}))
export default (dataOrFn = []) => WrappedComponent => {
class FirebaseConnect extends Component {
constructor (props, context) {
super(props, context)
this._firebaseEvents = []
this.firebase = null
}
static contextTypes = {
store: PropTypes.object.isRequired
};
componentWillMount () {
const { firebase, dispatch } = this.context.store
const linkFn = ensureCallable(dataOrFn)
const data = linkFn(this.props, firebase)
const { ref, helpers, storage, database, auth } = firebase
this.firebase = { ref, storage, database, auth, ...helpers }
this._firebaseEvents = getEventsFromDefinition(data)
watchEvents(firebase, dispatch, this._firebaseEvents)
}
componentWillUnmount () {
const {firebase} = this.context.store
unWatchEvents(firebase, this._firebaseEvents)
}
render () {
return (
<WrappedComponent
{...this.props}
{...this.state}
firebase={this.firebase}
/>
)
}
}
return FirebaseConnect
}