Skip to content

Commit d7dd84e

Browse files
Make Datastore optional
1 parent b614546 commit d7dd84e

File tree

10 files changed

+377
-292
lines changed

10 files changed

+377
-292
lines changed
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/**
2+
* @license
3+
* Copyright 2020 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import { Firestore } from './database';
19+
import { DatabaseInfo } from '../../../src/core/database_info';
20+
import {
21+
FirestoreClient,
22+
PersistenceSettings
23+
} from '../../../src/core/firestore_client';
24+
import { Code, FirestoreError } from '../../../src/util/error';
25+
import {
26+
ComponentProvider,
27+
MemoryComponentProvider
28+
} from '../../../src/core/component_provider';
29+
import { DEFAULT_HOST, DEFAULT_SSL } from '../../../lite/src/api/components';
30+
31+
// The components module manages the lifetime of dependencies of the Firestore
32+
// client. Dependencies can be lazily constructed and only one exists per
33+
// Firestore instance.
34+
35+
/**
36+
* An instance map that ensures only one FirestoreClient exists per Firestore
37+
* instance.
38+
*/
39+
const firestoreClientInstances = new Map<Firestore, Promise<FirestoreClient>>();
40+
41+
/**
42+
* Returns the initialized and started FirestoreClient for the given Firestore
43+
* instance. If none exists, creates a new FirestoreClient with memory
44+
* persistence. Callers must invoke removeFirestoreClient() when the Firestore
45+
* instance is terminated.
46+
*/
47+
export function getFirestoreClient(
48+
firestore: Firestore
49+
): Promise<FirestoreClient> {
50+
if (firestore._terminated) {
51+
throw new FirestoreError(
52+
Code.FAILED_PRECONDITION,
53+
'The client has already been terminated.'
54+
);
55+
}
56+
if (!firestoreClientInstances.has(firestore)) {
57+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
58+
initializeFirestoreClient(firestore, new MemoryComponentProvider(), {
59+
durable: false
60+
});
61+
}
62+
return firestoreClientInstances.get(firestore)!;
63+
}
64+
65+
/**
66+
* Creates a new FirestoreClient for the given Firestore instance. Throws if the
67+
* instance exists.
68+
*
69+
* @param firestore The Firestore instance for which to create the
70+
* FirestoreClient.
71+
* @param componentProvider The component provider to use.
72+
* @param persistenceSettings Settings for the component provider.
73+
*/
74+
export function initializeFirestoreClient(
75+
firestore: Firestore,
76+
componentProvider: ComponentProvider,
77+
persistenceSettings: PersistenceSettings
78+
): Promise<void> {
79+
if (firestore._initialized) {
80+
throw new FirestoreError(
81+
Code.FAILED_PRECONDITION,
82+
'Firestore has already been started and persistence can no longer ' +
83+
'be enabled. You can only enable persistence before calling ' +
84+
'any other methods on a Firestore object.'
85+
);
86+
}
87+
88+
const settings = firestore._getSettings();
89+
const databaseInfo = new DatabaseInfo(
90+
firestore._databaseId,
91+
firestore._persistenceKey,
92+
settings.host ?? DEFAULT_HOST,
93+
settings.ssl ?? DEFAULT_SSL,
94+
/** forceLongPolling= */ false
95+
);
96+
const firestoreClient = new FirestoreClient(
97+
firestore._credentials,
98+
firestore._queue
99+
);
100+
const initializationPromise = firestoreClient.start(
101+
databaseInfo,
102+
componentProvider,
103+
persistenceSettings
104+
);
105+
firestoreClientInstances.set(
106+
firestore,
107+
initializationPromise.then(() => firestoreClient)
108+
);
109+
return initializationPromise;
110+
}
111+
112+
/**
113+
* Removes and terminates the FirestoreClient for the given instance if it has
114+
* been started.
115+
*/
116+
export async function removeFirestoreClient(
117+
firestore: Firestore
118+
): Promise<void> {
119+
const firestoreClient = await firestoreClientInstances.get(firestore);
120+
if (firestoreClient) {
121+
firestoreClientInstances.delete(firestore);
122+
return firestoreClient.terminate();
123+
}
124+
}

0 commit comments

Comments
 (0)