@@ -19,7 +19,7 @@ import { debugAssert } from '../util/assert';
19
19
import { EventHandler } from '../util/misc' ;
20
20
import { ObjectMap } from '../util/obj_map' ;
21
21
import { canonifyQuery , Query , queryEquals , stringifyQuery } from './query' ;
22
- import { SyncEngine , SyncEngineListener } from './sync_engine' ;
22
+ import { SyncEngineListener } from './sync_engine' ;
23
23
import { OnlineState } from './types' ;
24
24
import { ChangeType , DocumentViewChange , ViewSnapshot } from './view_snapshot' ;
25
25
import { wrapInUserErrorIfRecoverable } from '../util/async_queue' ;
@@ -45,6 +45,10 @@ export interface Observer<T> {
45
45
* EventManager is responsible for mapping queries to query event emitters.
46
46
* It handles "fan-out". -- Identical queries will re-use the same watch on the
47
47
* backend.
48
+ *
49
+ * PORTING NOTE: On Web, EventManager `onListen` and `onUnlisten` need to be
50
+ * assigned to SyncEngine's `listen()` and `unlisten()` API before usage. This
51
+ * allows users to tree-shake the Watch logic.
48
52
*/
49
53
export class EventManager implements SyncEngineListener {
50
54
private queries = new ObjectMap < Query , QueryListenersInfo > (
@@ -56,11 +60,13 @@ export class EventManager implements SyncEngineListener {
56
60
57
61
private snapshotsInSyncListeners : Set < Observer < void > > = new Set ( ) ;
58
62
59
- constructor ( private syncEngine : SyncEngine ) {
60
- this . syncEngine . subscribe ( this ) ;
61
- }
63
+ /** Callback invoked when a Query is first listen to. */
64
+ onListen ?: ( query : Query ) => Promise < ViewSnapshot > ;
65
+ /** Callback invoked once all listeners to a Query are removed. */
66
+ onUnlisten ?: ( query : Query ) => Promise < void > ;
62
67
63
68
async listen ( listener : QueryListener ) : Promise < void > {
69
+ debugAssert ( ! ! this . onListen , 'onListen not set' ) ;
64
70
const query = listener . query ;
65
71
let firstListen = false ;
66
72
@@ -72,7 +78,7 @@ export class EventManager implements SyncEngineListener {
72
78
73
79
if ( firstListen ) {
74
80
try {
75
- queryInfo . viewSnap = await this . syncEngine . listen ( query ) ;
81
+ queryInfo . viewSnap = await this . onListen ( query ) ;
76
82
} catch ( e ) {
77
83
const firestoreError = wrapInUserErrorIfRecoverable (
78
84
e ,
@@ -102,6 +108,7 @@ export class EventManager implements SyncEngineListener {
102
108
}
103
109
104
110
async unlisten ( listener : QueryListener ) : Promise < void > {
111
+ debugAssert ( ! ! this . onUnlisten , 'onUnlisten not set' ) ;
105
112
const query = listener . query ;
106
113
let lastListen = false ;
107
114
@@ -116,7 +123,7 @@ export class EventManager implements SyncEngineListener {
116
123
117
124
if ( lastListen ) {
118
125
this . queries . delete ( query ) ;
119
- return this . syncEngine . unlisten ( query ) ;
126
+ return this . onUnlisten ( query ) ;
120
127
}
121
128
}
122
129
0 commit comments