@@ -27,6 +27,7 @@ import { ChangeType, DocumentViewChange, ViewSnapshot } from './view_snapshot';
27
27
import { Pipeline } from '../api/pipeline' ;
28
28
import { PipelineSnapshot } from '../api/snapshot' ;
29
29
import { PipelineResultView } from './sync_engine_impl' ;
30
+ import { canonifyPipeline , pipelineEq } from './pipeline-util' ;
30
31
31
32
/**
32
33
* Holds the listeners and the last received ViewSnapshot for a query being
@@ -50,6 +51,12 @@ export interface Observer<T> {
50
51
error : EventHandler < FirestoreError > ;
51
52
}
52
53
54
+ export type QueryOrPipeline = Query | Pipeline ;
55
+
56
+ export function isPipeline ( q : QueryOrPipeline ) : q is Pipeline {
57
+ return q instanceof Pipeline ;
58
+ }
59
+
53
60
/**
54
61
* EventManager is responsible for mapping queries to query event emitters.
55
62
* It handles "fan-out". -- Identical queries will re-use the same watch on the
@@ -61,14 +68,15 @@ export interface Observer<T> {
61
68
*/
62
69
export interface EventManager {
63
70
onListen ?: (
64
- query : Query ,
71
+ query : QueryOrPipeline ,
65
72
enableRemoteListen : boolean
66
73
) => Promise < ViewSnapshot > ;
67
- onUnlisten ?: ( query : Query , disableRemoteListen : boolean ) => Promise < void > ;
68
- onFirstRemoteStoreListen ?: ( query : Query ) => Promise < void > ;
69
- onLastRemoteStoreUnlisten ?: ( query : Query ) => Promise < void > ;
70
- // TODO(pipeline): consolidate query and pipeline
71
- onListenPipeline ?: ( pipeline : PipelineListener ) => Promise < void > ;
74
+ onUnlisten ?: (
75
+ query : QueryOrPipeline ,
76
+ disableRemoteListen : boolean
77
+ ) => Promise < void > ;
78
+ onFirstRemoteStoreListen ?: ( query : QueryOrPipeline ) => Promise < void > ;
79
+ onLastRemoteStoreUnlisten ?: ( query : QueryOrPipeline ) => Promise < void > ;
72
80
terminate ( ) : void ;
73
81
}
74
82
@@ -77,31 +85,34 @@ export function newEventManager(): EventManager {
77
85
}
78
86
79
87
export class EventManagerImpl implements EventManager {
80
- queries : ObjectMap < Query , QueryListenersInfo > = newQueriesObjectMap ( ) ;
88
+ queries : ObjectMap < QueryOrPipeline , QueryListenersInfo > =
89
+ newQueriesObjectMap ( ) ;
81
90
82
91
onlineState : OnlineState = OnlineState . Unknown ;
83
92
84
93
snapshotsInSyncListeners : Set < Observer < void > > = new Set ( ) ;
85
94
86
95
/** Callback invoked when a Query is first listen to. */
87
96
onListen ?: (
88
- query : Query ,
97
+ query : QueryOrPipeline ,
89
98
enableRemoteListen : boolean
90
99
) => Promise < ViewSnapshot > ;
91
100
/** Callback invoked once all listeners to a Query are removed. */
92
- onUnlisten ?: ( query : Query , disableRemoteListen : boolean ) => Promise < void > ;
93
- onListenPipeline ?: ( pipeline : PipelineListener ) => Promise < void > ;
101
+ onUnlisten ?: (
102
+ query : QueryOrPipeline ,
103
+ disableRemoteListen : boolean
104
+ ) => Promise < void > ;
94
105
95
106
/**
96
107
* Callback invoked when a Query starts listening to the remote store, while
97
108
* already listening to the cache.
98
109
*/
99
- onFirstRemoteStoreListen ?: ( query : Query ) => Promise < void > ;
110
+ onFirstRemoteStoreListen ?: ( query : QueryOrPipeline ) => Promise < void > ;
100
111
/**
101
112
* Callback invoked when a Query stops listening to the remote store, while
102
113
* still listening to the cache.
103
114
*/
104
- onLastRemoteStoreUnlisten ?: ( query : Query ) => Promise < void > ;
115
+ onLastRemoteStoreUnlisten ?: ( query : QueryOrPipeline ) => Promise < void > ;
105
116
106
117
terminate ( ) : void {
107
118
errorAllTargets (
@@ -111,10 +122,43 @@ export class EventManagerImpl implements EventManager {
111
122
}
112
123
}
113
124
114
- function newQueriesObjectMap ( ) : ObjectMap < Query , QueryListenersInfo > {
115
- return new ObjectMap < Query , QueryListenersInfo > (
116
- q => canonifyQuery ( q ) ,
117
- queryEquals
125
+ export function stringifyQueryOrPipeline ( q : QueryOrPipeline ) : string {
126
+ if ( isPipeline ( q ) ) {
127
+ return canonifyPipeline ( q ) ;
128
+ }
129
+
130
+ return stringifyQuery ( q ) ;
131
+ }
132
+
133
+ export function canonifyQueryOrPipeline ( q : QueryOrPipeline ) : string {
134
+ if ( isPipeline ( q ) ) {
135
+ return canonifyPipeline ( q ) ;
136
+ }
137
+
138
+ return canonifyQuery ( q ) ;
139
+ }
140
+
141
+ export function queryOrPipelineEqual (
142
+ left : QueryOrPipeline ,
143
+ right : QueryOrPipeline
144
+ ) : boolean {
145
+ if ( left instanceof Pipeline && right instanceof Pipeline ) {
146
+ return pipelineEq ( left , right ) ;
147
+ }
148
+ if (
149
+ ( left instanceof Pipeline && ! ( right instanceof Pipeline ) ) ||
150
+ ( ! ( left instanceof Pipeline ) && right instanceof Pipeline )
151
+ ) {
152
+ return false ;
153
+ }
154
+
155
+ return queryEquals ( left as Query , right as Query ) ;
156
+ }
157
+
158
+ function newQueriesObjectMap ( ) : ObjectMap < QueryOrPipeline , QueryListenersInfo > {
159
+ return new ObjectMap < QueryOrPipeline , QueryListenersInfo > (
160
+ q => canonifyQueryOrPipeline ( q ) ,
161
+ queryOrPipelineEqual
118
162
) ;
119
163
}
120
164
@@ -129,7 +173,6 @@ function validateEventManager(eventManagerImpl: EventManagerImpl): void {
129
173
! ! eventManagerImpl . onLastRemoteStoreUnlisten ,
130
174
'onLastRemoteStoreUnlisten not set'
131
175
) ;
132
- debugAssert ( ! ! eventManagerImpl . onListenPipeline , 'onListenPipeline not set' ) ;
133
176
}
134
177
135
178
const enum ListenerSetupAction {
@@ -194,7 +237,11 @@ export async function eventManagerListen(
194
237
} catch ( e ) {
195
238
const firestoreError = wrapInUserErrorIfRecoverable (
196
239
e as Error ,
197
- `Initialization of query '${ stringifyQuery ( listener . query ) } ' failed`
240
+ `Initialization of query '${
241
+ isPipeline ( listener . query )
242
+ ? canonifyPipeline ( listener . query )
243
+ : stringifyQuery ( listener . query )
244
+ } ' failed`
198
245
) ;
199
246
listener . onError ( firestoreError ) ;
200
247
return ;
@@ -220,25 +267,6 @@ export async function eventManagerListen(
220
267
}
221
268
}
222
269
223
- export async function eventManagerListenPipeline (
224
- eventManager : EventManager ,
225
- listener : PipelineListener
226
- ) : Promise < void > {
227
- const eventManagerImpl = debugCast ( eventManager , EventManagerImpl ) ;
228
- validateEventManager ( eventManagerImpl ) ;
229
-
230
- try {
231
- await eventManagerImpl . onListenPipeline ! ( listener ) ;
232
- } catch ( e ) {
233
- const firestoreError = wrapInUserErrorIfRecoverable (
234
- e as Error ,
235
- `Initialization of query '${ listener . pipeline } ' failed`
236
- ) ;
237
- listener . onError ( firestoreError ) ;
238
- return ;
239
- }
240
- }
241
-
242
270
export async function eventManagerUnlisten (
243
271
eventManager : EventManager ,
244
272
listener : QueryListener
@@ -312,13 +340,6 @@ export function eventManagerOnWatchChange(
312
340
}
313
341
}
314
342
315
- export function eventManagerOnPipelineWatchChange (
316
- eventManager : EventManager ,
317
- viewSnaps : PipelineResultView [ ]
318
- ) : void {
319
- const eventManagerImpl = debugCast ( eventManager , EventManagerImpl ) ;
320
- }
321
-
322
343
export function eventManagerOnWatchError (
323
344
eventManager : EventManager ,
324
345
query : Query ,
@@ -445,7 +466,7 @@ export class QueryListener {
445
466
private onlineState = OnlineState . Unknown ;
446
467
447
468
constructor (
448
- readonly query : Query ,
469
+ readonly query : QueryOrPipeline ,
449
470
private queryObserver : Observer < ViewSnapshot > ,
450
471
options ?: ListenOptions
451
472
) {
0 commit comments