@@ -22,30 +22,22 @@ export default class Database extends Base {
22
22
this . log . debug ( 'Created new Database instance' , this . options ) ;
23
23
24
24
this . persistenceEnabled = false ;
25
- this . successListener = null ;
26
- this . errorListener = null ;
27
- this . refs = { } ;
28
- this . dbSubscriptions = { } ; // { path: { modifier: { eventType: [Subscriptions] } } }
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 = { } ;
29
35
}
30
36
31
37
ref ( ...path : Array < string > ) {
32
38
return new Reference ( this , path ) ;
33
39
}
34
40
35
- storeRef ( key : string , instance : Reference ) : Promise < Reference > {
36
- if ( ! this . refs [ key ] ) {
37
- this . refs [ key ] = instance ;
38
- }
39
- return Promise . resolve ( this . refs [ key ] ) ;
40
- }
41
-
42
- unstoreRef ( key : string ) : Promise < void > {
43
- if ( this . refs [ key ] ) {
44
- delete this . refs [ key ] ;
45
- }
46
- return Promise . resolve ( ) ;
47
- }
48
-
49
41
setPersistence ( enable : boolean = true ) {
50
42
let promise ;
51
43
if ( this . persistenceEnabled !== enable ) {
@@ -59,148 +51,94 @@ export default class Database extends Base {
59
51
return promise ;
60
52
}
61
53
62
- handleDatabaseEvent ( evt : Object ) {
63
- const body = evt . body || { } ;
64
- const path = body . path ;
65
- const modifiersString = body . modifiersString || '' ;
66
- const modifier = modifiersString ;
67
- const eventName = body . eventName ;
68
- this . log . debug ( 'handleDatabaseEvent: ' , path , modifiersString , eventName , body . snapshot && body . snapshot . key ) ;
69
-
70
- // subscriptionsMap === { path: { modifier: { eventType: [Subscriptions] } } }
71
- const modifierMap = this . dbSubscriptions [ path ] ;
72
- if ( modifierMap ) {
73
- const eventTypeMap = modifierMap [ modifier ] ;
74
- if ( eventTypeMap ) {
75
- const callbacks = eventTypeMap [ eventName ] || [ ] ;
76
- this . log . debug ( ' -- about to fire its ' + callbacks . length + ' callbacks' ) ;
77
- callbacks . forEach ( cb => {
78
- if ( cb && typeof ( cb ) === 'function' ) {
79
- const snap = new Snapshot ( this , body . snapshot ) ;
80
- cb ( snap , body ) ;
81
- }
82
- } ) ;
83
- }
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
+ } ) ;
84
71
}
85
72
}
86
73
87
- handleDatabaseError ( evt : Object ) {
88
- this . log . debug ( 'handleDatabaseError ->' , evt ) ;
74
+ handleDatabaseError ( err : Object ) {
75
+ this . log . debug ( 'handleDatabaseError ->' , err ) ;
89
76
}
90
77
91
- on ( referenceKey : string , path : string , modifiersString : string , modifiers : Array < string > , evt : string , cb : ( ) = > void ) {
92
- this . log . debug ( 'adding on listener' , referenceKey , path , modifiers , evt ) ;
93
- const key = this . _pathKey ( path ) ;
94
-
95
- if ( ! this . dbSubscriptions [ key ] ) {
96
- this . dbSubscriptions [ key ] = { } ;
97
- }
98
-
99
- if ( ! this . dbSubscriptions [ key ] [ modifiersString ] ) {
100
- this . dbSubscriptions [ key ] [ modifiersString ] = { } ;
101
- }
102
-
103
- if ( ! this . dbSubscriptions [ key ] [ modifiersString ] [ evt ] ) {
104
- this . dbSubscriptions [ key ] [ modifiersString ] [ evt ] = [ ] ;
105
- }
106
-
107
- this . dbSubscriptions [ key ] [ modifiersString ] [ evt ] . push ( cb ) ;
108
-
109
- if ( ! this . successListener ) {
110
- this . successListener = FirestackDatabaseEvt
111
- . addListener (
112
- 'database_event' ,
113
- this . handleDatabaseEvent . bind ( this ) ) ;
114
- }
115
-
116
- if ( ! this . errorListener ) {
117
- this . errorListener = FirestackDatabaseEvt
118
- . addListener (
119
- 'database_error' ,
120
- this . handleDatabaseError . bind ( this ) ) ;
78
+ 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
+ }
88
+ } else {
89
+ this . dbSubscriptions [ dbHandle ] = {
90
+ [ eventName ] : [ cb ]
91
+ }
121
92
}
122
93
123
- return promisify ( 'on' , FirestackDatabase ) ( path , modifiersString , modifiers , evt ) . then ( ( ) => {
124
- return [ this . successListener , this . errorListener ] ;
125
- } ) ;
94
+ return promisify ( 'on' , FirestackDatabase ) ( path , modifiersString , modifiers , eventName ) ;
126
95
}
127
96
128
- off ( referenceKey : string , path : string , modifiersString : string , modifiers : Array < string > , eventName : string , origCB ?: ( ) => void ) {
129
- const pathKey = this . _pathKey ( path ) ;
130
- this . log . debug ( 'off() : ' , referenceKey , pathKey , modifiersString , eventName ) ;
131
- // Remove subscription
132
- if ( this . dbSubscriptions [ pathKey ] ) {
97
+ off ( path : string , modifiersString : string , eventName ?: string , origCB ?: ( ) => void ) {
98
+ const dbHandle = this . _dbHandle ( path , modifiersString ) ;
99
+ this . log . debug ( 'off() : ' , dbHandle , eventName ) ;
133
100
134
- if ( ! eventName || eventName === '' ) {
135
- // remove all listeners for this pathKey
136
- this . dbSubscriptions [ pathKey ] = { } ;
137
- }
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 ) ;
104
+ return Promise . resolve ( ) ;
105
+ }
138
106
139
- // TODO clean me - no need for this many conditionals
140
- if ( this . dbSubscriptions [ pathKey ] [ modifiersString ] ) {
141
- if ( this . dbSubscriptions [ pathKey ] [ modifiersString ] [ eventName ] ) {
142
- if ( origCB ) {
143
- // remove only the given callback
144
- this . dbSubscriptions [ pathKey ] [ modifiersString ] [ eventName ] . splice ( this . dbSubscriptions [ pathKey ] [ modifiersString ] [ eventName ] . indexOf ( origCB ) , 1 ) ;
145
- } else {
146
- // remove all callbacks for this path:modifier:eventType
147
- delete this . dbSubscriptions [ pathKey ] [ modifiersString ] [ eventName ] ;
148
- }
149
- } else {
150
- this . log . warn ( 'off() called, but not currently listening at that location (bad eventName)' , pathKey , modifiersString , eventName ) ;
151
- }
107
+ if ( eventName && origCB ) {
108
+ const i = this . dbSubscriptions [ dbHandle ] [ eventName ] . indexOf ( origCB ) ;
109
+ if ( i === - 1 ) {
110
+ this . log . warn ( 'off() called, but the callback specifed is not listening at that location (bad path)' , dbHandle , eventName ) ;
111
+ return Promise . resolve ( ) ;
152
112
} else {
153
- this . log . warn ( 'off() called, but not currently listening at that location (bad modifier)' , pathKey, modifiersString, eventName) ;
154
- }
155
-
156
- if ( Object . keys ( this . dbSubscriptions [ pathKey ] ) . length <= 0 ) {
157
- // there are no more subscriptions so we can unwatch
158
- delete this . dbSubscriptions [ pathKey ] ;
159
- }
160
- if ( Object . keys ( this . dbSubscriptions ) . length === 0 ) {
161
- if ( this . successListener ) {
162
- this . successListener . remove ( ) ;
163
- this . successListener = null ;
164
- }
165
- if ( this . errorListener ) {
166
- this . errorListener . remove ( ) ;
167
- this . errorListener = null ;
113
+ this . dbSubscriptions [ dbHandle ] [ eventName ] = this . dbSubscriptions [ dbHandle ] [ eventName ] . splice ( i , 1 ) ;
114
+ if ( this . dbSubscriptions [ dbHandle ] [ eventName ] . length > 0 ) {
115
+ return Promise . resolve ( ) ;
168
116
}
169
117
}
118
+ } else if ( eventName ) {
119
+ this . dbSubscriptions [ dbHandle ] [ eventName ] = [ ] ;
170
120
} else {
171
- this . log . warn ( 'off() called, but not currently listening at that location (bad path)' , pathKey , modifiersString , eventName ) ;
172
- }
173
-
174
- const subscriptions = [ this . successListener , this . errorListener ] ;
175
- const modifierMap = this . dbSubscriptions [ path ] ;
176
-
177
- if ( modifierMap && modifierMap [ modifiersString ] && modifierMap [ modifiersString ] [ eventName ] && modifierMap [ modifiersString ] [ eventName ] . length > 0 ) {
178
- return Promise . resolve ( subscriptions ) ;
121
+ this . dbSubscriptions [ dbHandle ] = { }
179
122
}
180
-
181
- return promisify ( 'off' , FirestackDatabase ) ( path , modifiersString , eventName ) . then ( ( ) => {
182
- // subscriptions.forEach(sub => sub.remove());
183
- // delete this.listeners[eventName];
184
- return subscriptions ;
185
- } ) ;
123
+ return promisify ( 'off' , FirestackDatabase ) ( path , modifiersString , eventName ) ;
186
124
}
187
125
188
126
cleanup ( ) {
189
- let promises = Object . keys ( this . refs )
190
- . map ( key => this . refs [ key ] )
191
- . map ( ref => ref . 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
+ } )
192
137
return Promise . all ( promises ) ;
193
138
}
194
139
195
- release ( ...path : Array < string > ) {
196
- const key = this . _pathKey ( ...path ) ;
197
- if ( this . refs [ key ] ) {
198
- delete this . refs [ key ] ;
199
- }
200
- }
201
-
202
- _pathKey ( ...path : Array < string > ) : string {
203
- return path . join ( '-' ) ;
140
+ _dbHandle ( path : string = '' , modifiersString : string = '' ) {
141
+ return path + '|' + modifiersString ;
204
142
}
205
143
206
144
goOnline ( ) {
0 commit comments