@@ -21,8 +21,8 @@ import {
21
21
SharedClientState ,
22
22
WebStorageSharedClientState
23
23
} from '../local/shared_client_state' ;
24
- import { LocalStore } from '../local/local_store' ;
25
- import { SyncEngine } from './sync_engine' ;
24
+ import { LocalStore , MultiTabLocalStore } from '../local/local_store' ;
25
+ import { MultiTabSyncEngine , SyncEngine } from './sync_engine' ;
26
26
import { RemoteStore } from '../remote/remote_store' ;
27
27
import { EventManager } from './event_manager' ;
28
28
import { AsyncQueue } from '../util/async_queue' ;
@@ -81,7 +81,7 @@ export interface ComponentProvider {
81
81
* Provides all components needed for Firestore with in-memory persistence.
82
82
* Uses EagerGC garbage collection.
83
83
*/
84
- export class MemoryComponentProvider {
84
+ export class MemoryComponentProvider implements ComponentProvider {
85
85
persistence ! : Persistence ;
86
86
sharedClientState ! : SharedClientState ;
87
87
localStore ! : LocalStore ;
@@ -106,24 +106,12 @@ export class MemoryComponentProvider {
106
106
OnlineStateSource . SharedClientState
107
107
) ;
108
108
this . remoteStore . syncEngine = this . syncEngine ;
109
- this . sharedClientState . syncEngine = this . syncEngine ;
110
109
110
+ await this . localStore . start ( ) ;
111
111
await this . sharedClientState . start ( ) ;
112
112
await this . remoteStore . start ( ) ;
113
- await this . localStore . start ( ) ;
114
113
115
- // NOTE: This will immediately call the listener, so we make sure to
116
- // set it after localStore / remoteStore are started.
117
- await this . persistence . setPrimaryStateListener ( async isPrimary => {
118
- await this . syncEngine . applyPrimaryState ( isPrimary ) ;
119
- if ( this . gcScheduler ) {
120
- if ( isPrimary && ! this . gcScheduler . started ) {
121
- this . gcScheduler . start ( this . localStore ) ;
122
- } else if ( ! isPrimary ) {
123
- this . gcScheduler . stop ( ) ;
124
- }
125
- }
126
- } ) ;
114
+ await this . remoteStore . applyPrimaryState ( this . syncEngine . isPrimaryClient ) ;
127
115
}
128
116
129
117
createEventManager ( cfg : ComponentConfiguration ) : EventManager {
@@ -149,7 +137,7 @@ export class MemoryComponentProvider {
149
137
! cfg . persistenceSettings . durable ,
150
138
'Can only start memory persistence'
151
139
) ;
152
- return new MemoryPersistence ( cfg . clientId , MemoryEagerDelegate . factory ) ;
140
+ return new MemoryPersistence ( MemoryEagerDelegate . factory ) ;
153
141
}
154
142
155
143
createRemoteStore ( cfg : ComponentConfiguration ) : RemoteStore {
@@ -192,13 +180,58 @@ export class MemoryComponentProvider {
192
180
* Provides all components needed for Firestore with IndexedDB persistence.
193
181
*/
194
182
export class IndexedDbComponentProvider extends MemoryComponentProvider {
183
+ persistence ! : IndexedDbPersistence ;
184
+
185
+ // TODO(tree-shaking): Create an IndexedDbComponentProvider and a
186
+ // MultiTabComponentProvider. The IndexedDbComponentProvider should depend
187
+ // on LocalStore and SyncEngine.
188
+ localStore ! : MultiTabLocalStore ;
189
+ syncEngine ! : MultiTabSyncEngine ;
190
+
191
+ async initialize ( cfg : ComponentConfiguration ) : Promise < void > {
192
+ await super . initialize ( cfg ) ;
193
+
194
+ // NOTE: This will immediately call the listener, so we make sure to
195
+ // set it after localStore / remoteStore are started.
196
+ await this . persistence . setPrimaryStateListener ( async isPrimary => {
197
+ await ( this . syncEngine as MultiTabSyncEngine ) . applyPrimaryState (
198
+ isPrimary
199
+ ) ;
200
+ if ( this . gcScheduler ) {
201
+ if ( isPrimary && ! this . gcScheduler . started ) {
202
+ this . gcScheduler . start ( this . localStore ) ;
203
+ } else if ( ! isPrimary ) {
204
+ this . gcScheduler . stop ( ) ;
205
+ }
206
+ }
207
+ } ) ;
208
+ }
209
+
210
+ createLocalStore ( cfg : ComponentConfiguration ) : LocalStore {
211
+ return new MultiTabLocalStore (
212
+ this . persistence ,
213
+ new IndexFreeQueryEngine ( ) ,
214
+ cfg . initialUser
215
+ ) ;
216
+ }
217
+
218
+ createSyncEngine ( cfg : ComponentConfiguration ) : SyncEngine {
219
+ const syncEngine = new MultiTabSyncEngine (
220
+ this . localStore ,
221
+ this . remoteStore ,
222
+ this . sharedClientState ,
223
+ cfg . initialUser ,
224
+ cfg . maxConcurrentLimboResolutions
225
+ ) ;
226
+ if ( this . sharedClientState instanceof WebStorageSharedClientState ) {
227
+ this . sharedClientState . syncEngine = syncEngine ;
228
+ }
229
+ return syncEngine ;
230
+ }
231
+
195
232
createGarbageCollectionScheduler (
196
233
cfg : ComponentConfiguration
197
234
) : GarbageCollectionScheduler | null {
198
- debugAssert (
199
- this . persistence instanceof IndexedDbPersistence ,
200
- 'IndexedDbComponentProvider should provide IndexedDBPersistence'
201
- ) ;
202
235
const garbageCollector = this . persistence . referenceDelegate
203
236
. garbageCollector ;
204
237
return new LruScheduler ( garbageCollector , cfg . asyncQueue ) ;
@@ -214,27 +247,23 @@ export class IndexedDbComponentProvider extends MemoryComponentProvider {
214
247
cfg . databaseInfo
215
248
) ;
216
249
const serializer = cfg . platform . newSerializer ( cfg . databaseInfo . databaseId ) ;
217
- return IndexedDbPersistence . createIndexedDbPersistence ( {
218
- allowTabSynchronization : cfg . persistenceSettings . synchronizeTabs ,
250
+ return new IndexedDbPersistence (
251
+ cfg . persistenceSettings . synchronizeTabs ,
219
252
persistenceKey ,
220
- clientId : cfg . clientId ,
221
- platform : cfg . platform ,
222
- queue : cfg . asyncQueue ,
253
+ cfg . clientId ,
254
+ cfg . platform ,
255
+ LruParams . withCacheSize ( cfg . persistenceSettings . cacheSizeBytes ) ,
256
+ cfg . asyncQueue ,
223
257
serializer ,
224
- lruParams : LruParams . withCacheSize (
225
- cfg . persistenceSettings . cacheSizeBytes
226
- ) ,
227
- sequenceNumberSyncer : this . sharedClientState
228
- } ) ;
258
+ this . sharedClientState
259
+ ) ;
229
260
}
230
261
231
262
createSharedClientState ( cfg : ComponentConfiguration ) : SharedClientState {
232
- debugAssert (
233
- cfg . persistenceSettings . durable ,
234
- 'Can only start durable persistence'
235
- ) ;
236
-
237
- if ( cfg . persistenceSettings . synchronizeTabs ) {
263
+ if (
264
+ cfg . persistenceSettings . durable &&
265
+ cfg . persistenceSettings . synchronizeTabs
266
+ ) {
238
267
if ( ! WebStorageSharedClientState . isAvailable ( cfg . platform ) ) {
239
268
throw new FirestoreError (
240
269
Code . UNIMPLEMENTED ,
0 commit comments