Skip to content

Commit efc7595

Browse files
author
Brian Chen
committed
cleaned up
1 parent 806aabb commit efc7595

File tree

6 files changed

+81
-17
lines changed

6 files changed

+81
-17
lines changed

packages/firebase/index.d.ts

+8
Original file line numberDiff line numberDiff line change
@@ -6226,6 +6226,14 @@ declare namespace firebase.firestore {
62266226
* multiple tabs, please use `synchronizeTabs: true` instead.
62276227
*/
62286228
experimentalTabSynchronization?: boolean;
6229+
6230+
/**
6231+
* Whether to force enable persistence for the client. This cannot be used
6232+
* with `synchronizeTabs:true` and is primarily intended for use with Web
6233+
* Workers. Setting this to 'true' will enable persistence, but cause other
6234+
* tabs using persistence to fail.
6235+
*/
6236+
experimentalForce?: boolean;
62296237
}
62306238

62316239
export type LogLevel = 'debug' | 'error' | 'silent';

packages/firestore-types/index.d.ts

+8
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,14 @@ export interface PersistenceSettings {
122122
* multiple tabs, please use `synchronizeTabs: true` instead.
123123
*/
124124
experimentalTabSynchronization?: boolean;
125+
126+
/**
127+
* Whether to force enable persistence for the client. This cannot be used
128+
* with `synchronizeTabs:true` and is primarily intended for use with Web
129+
* Workers. Setting this to 'true' will enable persistence, but cause other
130+
* tabs using persistence to fail.
131+
*/
132+
experimentalForce?: boolean;
125133
}
126134

127135
export type LogLevel = 'debug' | 'error' | 'silent';

packages/firestore/src/api/database.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ export class Firestore implements firestore.FirebaseFirestore, FirebaseService {
386386
}
387387

388388
let synchronizeTabs = false;
389+
let experimentalForce = false;
389390

390391
if (settings) {
391392
if (settings.experimentalTabSynchronization !== undefined) {
@@ -402,12 +403,16 @@ export class Firestore implements firestore.FirebaseFirestore, FirebaseService {
402403
: settings.experimentalTabSynchronization,
403404
DEFAULT_SYNCHRONIZE_TABS
404405
);
406+
experimentalForce = settings.experimentalForce
407+
? settings.experimentalForce
408+
: false;
405409
}
406410

407411
return this.configureClient(
408412
new IndexedDbPersistenceSettings(
409413
this._settings.cacheSizeBytes,
410-
synchronizeTabs
414+
synchronizeTabs,
415+
experimentalForce
411416
)
412417
);
413418
}

packages/firestore/src/core/firestore_client.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ const DOM_EXCEPTION_QUOTA_EXCEEDED = 22;
7373
export class IndexedDbPersistenceSettings {
7474
constructor(
7575
readonly cacheSizeBytes: number,
76-
readonly synchronizeTabs: boolean
76+
readonly synchronizeTabs: boolean,
77+
readonly force: boolean
7778
) {}
7879

7980
lruParams(): LruParams {
@@ -343,7 +344,8 @@ export class FirestoreClient {
343344
) {
344345
throw new FirestoreError(
345346
Code.UNIMPLEMENTED,
346-
'IndexedDB persistence is only available on platforms that support LocalStorage.'
347+
'IndexedDB persistence with synchronizedTabs is only available on ' +
348+
'platforms that support LocalStorage.'
347349
);
348350
}
349351

@@ -358,7 +360,6 @@ export class FirestoreClient {
358360
user
359361
)
360362
: new MemorySharedClientState();
361-
362363
const persistence = await IndexedDbPersistence.createIndexedDbPersistence(
363364
{
364365
allowTabSynchronization: settings.synchronizeTabs,
@@ -368,7 +369,8 @@ export class FirestoreClient {
368369
queue: this.asyncQueue,
369370
serializer,
370371
lruParams,
371-
sequenceNumberSyncer: this.sharedClientState
372+
sequenceNumberSyncer: this.sharedClientState,
373+
force: settings.force
372374
}
373375
);
374376

packages/firestore/src/local/indexeddb_persistence.ts

+41-11
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ export class IndexedDbPersistence implements Persistence {
197197
queue: AsyncQueue;
198198
serializer: JsonProtoSerializer;
199199
sequenceNumberSyncer: SequenceNumberSyncer;
200+
force: boolean;
200201
}): Promise<IndexedDbPersistence> {
201202
if (!IndexedDbPersistence.isAvailable()) {
202203
throw new FirestoreError(
@@ -213,14 +214,15 @@ export class IndexedDbPersistence implements Persistence {
213214
options.lruParams,
214215
options.queue,
215216
options.serializer,
216-
options.sequenceNumberSyncer
217+
options.sequenceNumberSyncer,
218+
options.force
217219
);
218220
await persistence.start();
219221
return persistence;
220222
}
221223

222224
private readonly document: Document | null;
223-
private readonly window: Window;
225+
private readonly window: Window | null;
224226

225227
// Technically these types should be `| undefined` because they are
226228
// initialized asynchronously by start(), but that would be more misleading
@@ -254,7 +256,7 @@ export class IndexedDbPersistence implements Persistence {
254256
private readonly queryCache: IndexedDbQueryCache;
255257
private readonly indexManager: IndexedDbIndexManager;
256258
private readonly remoteDocumentCache: IndexedDbRemoteDocumentCache;
257-
private readonly webStorage: Storage;
259+
private readonly webStorage: Storage | null;
258260
readonly referenceDelegate: IndexedDbLruDelegate;
259261

260262
private constructor(
@@ -265,7 +267,8 @@ export class IndexedDbPersistence implements Persistence {
265267
lruParams: LruParams,
266268
private readonly queue: AsyncQueue,
267269
serializer: JsonProtoSerializer,
268-
private readonly sequenceNumberSyncer: SequenceNumberSyncer
270+
private readonly sequenceNumberSyncer: SequenceNumberSyncer,
271+
private readonly takeoverPrimary: boolean
269272
) {
270273
this.referenceDelegate = new IndexedDbLruDelegate(this, lruParams);
271274
this.dbName = persistenceKey + IndexedDbPersistence.MAIN_DATABASE;
@@ -285,9 +288,11 @@ export class IndexedDbPersistence implements Persistence {
285288
this.window = platform.window;
286289
this.webStorage = this.window.localStorage;
287290
} else {
288-
throw new FirestoreError(
289-
Code.UNIMPLEMENTED,
290-
'IndexedDB persistence is only available on platforms that support LocalStorage.'
291+
this.window = platform.window;
292+
this.webStorage = null;
293+
log.error(
294+
LOG_TAG,
295+
'LocalStorage is unavailable. Multi-tab functionality may not be supported.'
291296
);
292297
}
293298
}
@@ -299,7 +304,6 @@ export class IndexedDbPersistence implements Persistence {
299304
*/
300305
private start(): Promise<void> {
301306
assert(!this.started, 'IndexedDbPersistence double-started!');
302-
assert(this.window !== null, "Expected 'window' to be defined");
303307

304308
return SimpleDb.openOrCreate(
305309
this.dbName,
@@ -526,9 +530,11 @@ export class IndexedDbPersistence implements Persistence {
526530
// the client atomically, but we can't. So we opt to delete the IndexedDb
527531
// entries first to avoid potentially reviving a zombied client.
528532
inactiveClients.forEach(inactiveClient => {
529-
this.window.localStorage.removeItem(
530-
this.zombiedClientLocalStorageKey(inactiveClient.clientId)
531-
);
533+
if (this.webStorage) {
534+
this.webStorage.removeItem(
535+
this.zombiedClientLocalStorageKey(inactiveClient.clientId)
536+
);
537+
}
532538
});
533539
}
534540
}
@@ -551,6 +557,10 @@ export class IndexedDbPersistence implements Persistence {
551557

552558
/** Checks whether `client` is the local client. */
553559
private isLocalClient(client: DbPrimaryClient | null): boolean {
560+
console.error('this id', this.clientId);
561+
if (client) {
562+
console.error('client id', client.ownerId);
563+
}
554564
return client ? client.ownerId === this.clientId : false;
555565
}
556566

@@ -590,6 +600,11 @@ export class IndexedDbPersistence implements Persistence {
590600
}
591601

592602
if (!this.isLocalClient(currentPrimary)) {
603+
if (this.takeoverPrimary) {
604+
console.error('WHOOOOO LETS TAKE IT');
605+
return true;
606+
}
607+
console.error('gg no primary for you');
593608
if (!currentPrimary!.allowTabSynchronization) {
594609
// Fail the `canActAsPrimary` check if the current leaseholder has
595610
// not opted into multi-tab synchronization. If this happens at
@@ -974,6 +989,9 @@ export class IndexedDbPersistence implements Persistence {
974989
* handler.
975990
*/
976991
private attachWindowUnloadHook(): void {
992+
if (!this.window) {
993+
return;
994+
}
977995
if (typeof this.window.addEventListener === 'function') {
978996
this.windowUnloadHandler = () => {
979997
// Note: In theory, this should be scheduled on the AsyncQueue since it
@@ -992,6 +1010,9 @@ export class IndexedDbPersistence implements Persistence {
9921010
}
9931011

9941012
private detachWindowUnloadHook(): void {
1013+
if (!this.window) {
1014+
return;
1015+
}
9951016
if (this.windowUnloadHandler) {
9961017
assert(
9971018
typeof this.window.removeEventListener === 'function',
@@ -1008,6 +1029,9 @@ export class IndexedDbPersistence implements Persistence {
10081029
* cleanup logic in `shutdown()`.
10091030
*/
10101031
private isClientZombied(clientId: ClientId): boolean {
1032+
if (!this.webStorage) {
1033+
return false;
1034+
}
10111035
try {
10121036
const isZombied =
10131037
this.webStorage.getItem(this.zombiedClientLocalStorageKey(clientId)) !==
@@ -1031,6 +1055,9 @@ export class IndexedDbPersistence implements Persistence {
10311055
* clients are ignored during primary tab selection.
10321056
*/
10331057
private markClientZombied(): void {
1058+
if (!this.webStorage) {
1059+
return;
1060+
}
10341061
try {
10351062
this.webStorage.setItem(
10361063
this.zombiedClientLocalStorageKey(this.clientId),
@@ -1044,6 +1071,9 @@ export class IndexedDbPersistence implements Persistence {
10441071

10451072
/** Removes the zombied client entry if it exists. */
10461073
private removeClientZombiedEntry(): void {
1074+
if (!this.webStorage) {
1075+
return;
1076+
}
10471077
try {
10481078
this.webStorage.removeItem(
10491079
this.zombiedClientLocalStorageKey(this.clientId)

packages/firestore/src/local/simple_db.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,14 @@ export class SimpleDb {
6666
// suggests IE9 and older WebKit browsers handle upgrade
6767
// differently. They expect setVersion, as described here:
6868
// https://developer.mozilla.org/en-US/docs/Web/API/IDBVersionChangeRequest/setVersion
69-
const request = window.indexedDB.open(name, version);
69+
70+
let request: IDBOpenDBRequest;
71+
// Support Web Workers, which don't have `window` global variable.
72+
if (indexedDB !== undefined) {
73+
request = indexedDB.open(name, version);
74+
} else {
75+
request = window.indexedDB.open(name, version);
76+
}
7077

7178
request.onsuccess = (event: Event) => {
7279
const db = (event.target as IDBOpenDBRequest).result;
@@ -132,6 +139,10 @@ export class SimpleDb {
132139

133140
/** Returns true if IndexedDB is available in the current environment. */
134141
static isAvailable(): boolean {
142+
// If IndexedDb is available directly (ex: in case of web workers).
143+
if (typeof indexedDB !== 'undefined') {
144+
return true;
145+
}
135146
if (typeof window === 'undefined' || window.indexedDB == null) {
136147
return false;
137148
}

0 commit comments

Comments
 (0)