2
2
* @flow
3
3
* Database representation wrapper
4
4
*/
5
- 'use strict' ;
6
5
import { NativeModules , NativeEventEmitter } from 'react-native' ;
7
- const FirestackDatabase = NativeModules . FirestackDatabase ;
8
- const FirestackDatabaseEvt = new NativeEventEmitter ( FirestackDatabase ) ;
9
-
10
- import { promisify } from './../../utils' ;
11
-
12
6
import { Base } from './../base' ;
13
- import Reference from './reference.js' ;
14
7
import Snapshot from './snapshot.js' ;
8
+ import Reference from './reference.js' ;
9
+ import { promisify , isFunction } from './../../utils' ;
10
+
11
+ const FirestackDatabase = NativeModules . FirestackDatabase ;
12
+ const FirestackDatabaseEvt = new NativeEventEmitter ( FirestackDatabase ) ;
15
13
16
14
/**
17
15
* @class Database
18
16
*/
19
17
export default class Database extends Base {
20
18
constructor ( firestack : Object , options : Object = { } ) {
21
19
super ( firestack , options ) ;
22
- this . log . debug ( 'Created new Database instance' , this . options ) ;
23
-
20
+ this . subscriptions = { } ;
24
21
this . persistenceEnabled = false ;
25
- this . successListener = FirestackDatabaseEvt
26
- . addListener (
27
- 'database_event' ,
28
- event => this . handleDatabaseEvent ( event ) ) ;
29
- this . errorListener = FirestackDatabaseEvt
30
- . addListener (
31
- 'database_error' ,
32
- err => this . handleDatabaseError ( err ) ) ;
33
-
34
- this . dbSubscriptions = { } ;
22
+ this . namespace = 'firestack:database' ;
23
+
24
+ this . successListener = FirestackDatabaseEvt . addListener (
25
+ 'database_event' ,
26
+ event => this . _handleDatabaseEvent ( event )
27
+ ) ;
28
+
29
+ this . errorListener = FirestackDatabaseEvt . addListener (
30
+ 'database_error' ,
31
+ err => this . _handleDatabaseError ( err )
32
+ ) ;
33
+
34
+ this . log . debug ( 'Created new Database instance' , this . options ) ;
35
35
}
36
36
37
+ /**
38
+ * Returns a new firestack reference instance
39
+ * @param path
40
+ * @returns {Reference }
41
+ */
37
42
ref ( ...path : Array < string > ) {
38
43
return new Reference ( this , path ) ;
39
44
}
40
45
46
+ /**
47
+ * Enabled / disable database persistence
48
+ * @param enable
49
+ * @returns {* }
50
+ */
41
51
setPersistence ( enable : boolean = true ) {
42
- let promise ;
43
52
if ( this . persistenceEnabled !== enable ) {
44
53
this . log . debug ( `${ enable ? 'Enabling' : 'Disabling' } persistence` ) ;
45
- promise = this . whenReady ( promisify ( 'enablePersistence' , FirestackDatabase ) ( enable ) ) ;
46
54
this . persistenceEnabled = enable ;
47
- } else {
48
- promise = this . whenReady ( Promise . resolve ( { status : 'Already enabled' } ) )
49
- }
50
-
51
- return promise ;
52
- }
53
-
54
- handleDatabaseEvent ( event : Object ) {
55
- const body = event . body || { } ;
56
- const { path, modifiersString, eventName, snapshot } = body ;
57
- const dbHandle = this . _dbHandle ( path , modifiersString ) ;
58
- this . log . debug ( 'handleDatabaseEvent: ' , dbHandle , eventName , snapshot && snapshot . key ) ;
59
-
60
- if ( this . dbSubscriptions [ dbHandle ] && this . dbSubscriptions [ dbHandle ] [ eventName ] ) {
61
- this . dbSubscriptions [ dbHandle ] [ eventName ] . forEach ( cb => {
62
- if ( cb && typeof ( cb ) === 'function' ) {
63
- const snap = new Snapshot ( this , snapshot ) ;
64
- cb ( snap , body ) ;
65
- }
66
- } )
67
- } else {
68
- FirestackDatabase . off ( path , modifiersString , eventName , ( ) => {
69
- this . log . debug ( 'handleDatabaseEvent: No JS listener registered, removed native listener' , dbHandle , eventName ) ;
70
- } ) ;
55
+ return this . whenReady ( promisify ( 'enablePersistence' , FirestackDatabase ) ( enable ) ) ;
71
56
}
72
- }
73
57
74
- handleDatabaseError ( err : Object ) {
75
- this . log . debug ( 'handleDatabaseError ->' , err ) ;
58
+ return this . whenReady ( Promise . resolve ( { status : 'Already enabled' } ) ) ;
76
59
}
77
60
61
+ /**
62
+ *
63
+ * @param path
64
+ * @param modifiersString
65
+ * @param modifiers
66
+ * @param eventName
67
+ * @param cb
68
+ * @returns {* }
69
+ */
78
70
on ( path : string , modifiersString : string , modifiers : Array < string > , eventName : string , cb : ( ) = > void ) {
79
- const dbHandle = this . _dbHandle ( path , modifiersString ) ;
80
- this . log . debug ( 'adding on listener' , dbHandle ) ;
81
-
82
- if ( this . dbSubscriptions [ dbHandle ] ) {
83
- if ( this . dbSubscriptions [ dbHandle ] [ eventName ] ) {
84
- this . dbSubscriptions [ dbHandle ] [ eventName ] . push ( cb ) ;
85
- } else {
86
- this . dbSubscriptions [ dbHandle ] [ eventName ] = [ cb ] ;
87
- }
71
+ const handle = this . _handle ( path , modifiersString ) ;
72
+ this . log . debug ( 'adding on listener' , handle ) ;
73
+
74
+ if ( this . subscriptions [ handle ] ) {
75
+ if ( this . subscriptions [ handle ] [ eventName ] ) this . subscriptions [ handle ] [ eventName ] . push ( cb ) ;
76
+ else this . subscriptions [ handle ] [ eventName ] = [ cb ] ;
88
77
} else {
89
- this . dbSubscriptions [ dbHandle ] = {
90
- [ eventName ] : [ cb ]
91
- }
78
+ this . subscriptions [ handle ] = { [ eventName ] : [ cb ] } ;
92
79
}
93
80
94
81
return promisify ( 'on' , FirestackDatabase ) ( path , modifiersString , modifiers , eventName ) ;
95
82
}
96
83
84
+ /**
85
+ *
86
+ * @param path
87
+ * @param modifiersString
88
+ * @param eventName
89
+ * @param origCB
90
+ * @returns {* }
91
+ */
97
92
off ( path : string , modifiersString : string , eventName ?: string , origCB ?: ( ) => void ) {
98
- const dbHandle = this . _dbHandle ( path , modifiersString ) ;
99
- this . log . debug ( 'off() : ' , dbHandle , eventName ) ;
93
+ const handle = this . _handle ( path , modifiersString ) ;
94
+ this . log . debug ( 'off() : ' , handle , eventName ) ;
100
95
101
- if ( ! this . dbSubscriptions [ dbHandle ]
102
- || ( eventName && ! this . dbSubscriptions [ dbHandle ] [ eventName ] ) ) {
103
- this . log . warn ( 'off() called, but not currently listening at that location (bad path)' , dbHandle , eventName ) ;
96
+ if ( ! this . subscriptions [ handle ] || ( eventName && ! this . subscriptions [ handle ] [ eventName ] ) ) {
97
+ this . log . warn ( 'off() called, but not currently listening at that location (bad path)' , handle , eventName ) ;
104
98
return Promise . resolve ( ) ;
105
99
}
106
100
107
101
if ( eventName && origCB ) {
108
- const i = this . dbSubscriptions [ dbHandle ] [ eventName ] . indexOf ( origCB ) ;
102
+ const i = this . subscriptions [ handle ] [ eventName ] . indexOf ( origCB ) ;
109
103
if ( i === - 1 ) {
110
- this . log . warn ( 'off() called, but the callback specifed is not listening at that location (bad path)' , dbHandle , eventName ) ;
104
+ this . log . warn ( 'off() called, but the callback specifed is not listening at that location (bad path)' , handle , eventName ) ;
105
+ return Promise . resolve ( ) ;
106
+ }
107
+
108
+ this . subscriptions [ handle ] [ eventName ] = this . subscriptions [ handle ] [ eventName ] . splice ( i , 1 ) ;
109
+
110
+ if ( this . subscriptions [ handle ] [ eventName ] . length > 0 ) {
111
111
return Promise . resolve ( ) ;
112
- } else {
113
- this . dbSubscriptions [ dbHandle ] [ eventName ] = this . dbSubscriptions [ dbHandle ] [ eventName ] . splice ( i , 1 ) ;
114
- if ( this . dbSubscriptions [ dbHandle ] [ eventName ] . length > 0 ) {
115
- return Promise . resolve ( ) ;
116
- }
117
112
}
118
113
} else if ( eventName ) {
119
- this . dbSubscriptions [ dbHandle ] [ eventName ] = [ ] ;
114
+ this . subscriptions [ handle ] [ eventName ] = [ ] ;
120
115
} else {
121
- this . dbSubscriptions [ dbHandle ] = { }
116
+ this . subscriptions [ handle ] = { } ;
122
117
}
118
+
123
119
return promisify ( 'off' , FirestackDatabase ) ( path , modifiersString , eventName ) ;
124
120
}
125
121
122
+ /**
123
+ * Removes all event handlers and their native subscriptions
124
+ * @returns {Promise.<*> }
125
+ */
126
126
cleanup ( ) {
127
- let promises = [ ] ;
128
- Object . keys ( this . dbSubscriptions ) . forEach ( dbHandle => {
129
- Object . keys ( this . dbSubscriptions [ dbHandle ] ) . forEach ( eventName => {
130
- let separator = dbHandle . indexOf ( '|' ) ;
131
- let path = dbHandle . substring ( 0 , separator ) ;
132
- let modifiersString = dbHandle . substring ( separator + 1 ) ;
133
-
134
- promises . push ( this . off ( path , modifiersString , eventName ) )
135
- } )
136
- } )
137
- return Promise . all ( promises ) ;
138
- }
127
+ const promises = [ ] ;
128
+ Object . keys ( this . subscriptions ) . forEach ( ( handle ) => {
129
+ Object . keys ( this . subscriptions [ handle ] ) . forEach ( ( eventName ) => {
130
+ const separator = handle . indexOf ( '|' ) ;
131
+ const path = handle . substring ( 0 , separator ) ;
132
+ const modifiersString = handle . substring ( separator + 1 ) ;
133
+ promises . push ( this . off ( path , modifiersString , eventName ) ) ;
134
+ } ) ;
135
+ } ) ;
139
136
140
- _dbHandle ( path : string = '' , modifiersString : string = '' ) {
141
- return path + '|' + modifiersString ;
137
+ return Promise . all ( promises ) ;
142
138
}
143
139
144
140
goOnline ( ) {
@@ -149,7 +145,52 @@ export default class Database extends Base {
149
145
FirestackDatabase . goOffline ( ) ;
150
146
}
151
147
152
- get namespace ( ) : string {
153
- return 'firestack :database ';
148
+ /**
149
+ * INTERNALS
150
+ */
151
+
152
+
153
+ /**
154
+ *
155
+ * @param path
156
+ * @param modifiersString
157
+ * @returns {string }
158
+ * @private
159
+ */
160
+ _dbHandle ( path : string = '' , modifiersString : string = '' ) {
161
+ return `${ path } |${ modifiersString } ` ;
162
+ }
163
+
164
+
165
+ /**
166
+ *
167
+ * @param event
168
+ * @private
169
+ */
170
+ _handleDatabaseEvent ( event : Object ) {
171
+ const body = event . body || { } ;
172
+ const { path, modifiersString, eventName, snapshot } = body ;
173
+ const handle = this . _handle ( path , modifiersString ) ;
174
+
175
+ this . log . debug ( '_handleDatabaseEvent: ' , handle , eventName , snapshot && snapshot . key ) ;
176
+
177
+ if ( this . subscriptions [ handle ] && this . subscriptions [ handle ] [ eventName ] ) {
178
+ this . subscriptions [ handle ] [ eventName ] . forEach ( ( cb ) => {
179
+ if ( isFunction ( cb ) ) cb ( new Snapshot ( this , snapshot ) , body ) ;
180
+ } ) ;
181
+ } else {
182
+ FirestackDatabase . off ( path , modifiersString , eventName , ( ) => {
183
+ this . log . debug ( '_handleDatabaseEvent: No JS listener registered, removed native listener' , handle , eventName ) ;
184
+ } ) ;
185
+ }
186
+ }
187
+
188
+ /**
189
+ *
190
+ * @param err
191
+ * @private
192
+ */
193
+ _handleDatabaseError ( err : Object ) {
194
+ this . log . debug ( '_handleDatabaseError ->' , err ) ;
154
195
}
155
196
}
0 commit comments