Skip to content

Commit 0b42fc1

Browse files
Merge branch 'master' into multitab-instancestate
2 parents ede438e + 453677f commit 0b42fc1

32 files changed

+274
-198
lines changed

packages/firestore/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
"author": "Firebase <[email protected]> (https://firebase.google.com/)",
66
"scripts": {
77
"dev": "gulp dev",
8-
"lint": "tslint -c tslint.json src/**/*.ts test/**/*.ts",
8+
"lint": "tslint -p tsconfig.json -c tslint.json src/**/*.ts test/**/*.ts",
9+
"lint:fix": "tslint --fix -p tsconfig.json -c tslint.json src/**/*.ts test/**/*.ts",
910
"test": "run-s lint test:all",
1011
"test:all": "run-p test:browser test:node",
1112
"test:browser": "karma start --single-run",

packages/firestore/src/api/credentials.ts

-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import { User } from '../auth/user';
1818
import { assert, fail } from '../util/assert';
1919
import { Code, FirestoreError } from '../util/error';
20-
import { AnyJs } from '../util/misc';
2120
import { FirebaseApp } from '@firebase/app-types';
2221
import { _FirebaseApp } from '@firebase/app-types/private';
2322

packages/firestore/src/api/database.ts

+1-5
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,7 @@ import {
3333
RelationOp
3434
} from '../core/query';
3535
import { Transaction as InternalTransaction } from '../core/transaction';
36-
import {
37-
ChangeType,
38-
DocumentViewChange,
39-
ViewSnapshot
40-
} from '../core/view_snapshot';
36+
import { ChangeType, ViewSnapshot } from '../core/view_snapshot';
4137
import { Document, MaybeDocument, NoDocument } from '../model/document';
4238
import { DocumentKey } from '../model/document_key';
4339
import {

packages/firestore/src/api/user_data_converter.ts

-9
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414
* limitations under the License.
1515
*/
1616

17-
import * as firestore from '@firebase/firestore-types';
18-
1917
import { DatabaseId } from '../core/database_info';
2018
import { Timestamp } from '../core/timestamp';
2119
import { DocumentKey } from '../model/document_key';
@@ -248,13 +246,6 @@ class ParseContext {
248246
throw this.createError('Document fields cannot begin and end with __');
249247
}
250248
}
251-
252-
private isWrite(): boolean {
253-
return (
254-
this.dataSource === UserDataSource.Set ||
255-
this.dataSource === UserDataSource.Update
256-
);
257-
}
258249
}
259250
/**
260251
* An interface that allows arbitrary pre-converting of user data. This

packages/firestore/src/auth/user.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,19 @@ export class User {
2929

3030
constructor(readonly uid: string | null) {}
3131

32-
isUnauthenticated(): boolean {
33-
return this.uid == null;
32+
isAuthenticated(): boolean {
33+
return this.uid != null;
3434
}
3535

3636
/**
3737
* Returns a key representing this user, suitable for inclusion in a
3838
* dictionary.
3939
*/
4040
toKey(): string {
41-
if (this.isUnauthenticated()) {
42-
return 'anonymous-user';
43-
} else {
41+
if (this.isAuthenticated()) {
4442
return 'uid:' + this.uid;
43+
} else {
44+
return 'anonymous-user';
4545
}
4646
}
4747

packages/firestore/src/core/event_manager.ts

-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import { ChangeType, ViewSnapshot } from './view_snapshot';
2222
import { DocumentSet } from '../model/document_set';
2323
import { assert } from '../util/assert';
2424
import { EventHandler } from '../util/misc';
25-
import * as obj from '../util/obj';
2625
import { ObjectMap } from '../util/obj_map';
2726

2827
/**

packages/firestore/src/core/firestore_client.ts

-1
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,6 @@ export class FirestoreClient {
274274
this.databaseInfo.databaseId
275275
);
276276
const datastore = new Datastore(
277-
this.databaseInfo,
278277
this.asyncQueue,
279278
connection,
280279
this.credentials,

packages/firestore/src/local/indexeddb_mutation_queue.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export class IndexedDbMutationQueue implements MutationQueue {
8080
// For the moment store these together in the same mutations table assuming
8181
// that empty userIDs aren't allowed.
8282
assert(user.uid !== '', 'UserID must not be an empty string.');
83-
const userId = user.isUnauthenticated() ? '' : user.uid!;
83+
const userId = user.isAuthenticated() ? user.uid! : '';
8484
return new IndexedDbMutationQueue(userId, serializer);
8585
}
8686

@@ -222,7 +222,6 @@ export class IndexedDbMutationQueue implements MutationQueue {
222222
.next(() => {
223223
const promises: Array<PersistencePromise<void>> = [];
224224
for (const mutation of mutations) {
225-
const encodedPath = EncodedResourcePath.encode(mutation.key.path);
226225
const indexKey = DbDocumentMutation.key(
227226
this.userId,
228227
mutation.key.path,
@@ -379,7 +378,6 @@ export class IndexedDbMutationQueue implements MutationQueue {
379378
this.userId,
380379
queryPath
381380
);
382-
const encodedQueryPath = indexPrefix[1];
383381
const indexStart = IDBKeyRange.lowerBound(indexPrefix);
384382

385383
// Collect up unique batchIDs encountered during a scan of the index. Use a
@@ -516,8 +514,8 @@ export class IndexedDbMutationQueue implements MutationQueue {
516514
const startRange = IDBKeyRange.lowerBound(indexKey);
517515
let containsKey = false;
518516
return documentMutationsStore(txn)
519-
.iterate({ range: startRange, keysOnly: true }, (key, _, control) => {
520-
const [userID, keyPath, batchID] = key;
517+
.iterate({ range: startRange, keysOnly: true }, (key, value, control) => {
518+
const [userID, keyPath, /*batchID*/ _] = key;
521519
if (userID === this.userId && keyPath === encodedPath) {
522520
containsKey = true;
523521
}

packages/firestore/src/local/indexeddb_query_cache.ts

-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
* limitations under the License.
1515
*/
1616

17-
import * as api from '../protos/firestore_proto_api';
1817
import { Query } from '../core/query';
1918
import { SnapshotVersion } from '../core/snapshot_version';
2019
import { Timestamp } from '../core/timestamp';
@@ -27,7 +26,6 @@ import { immediateSuccessor } from '../util/misc';
2726
import * as EncodedResourcePath from './encoded_resource_path';
2827
import { GarbageCollector } from './garbage_collector';
2928
import {
30-
DbQuery,
3129
DbTarget,
3230
DbTargetDocument,
3331
DbTargetDocumentKey,
@@ -237,7 +235,6 @@ export class IndexedDbQueryCache implements QueryCache {
237235
txn: PersistenceTransaction,
238236
targetId: TargetId
239237
): PersistencePromise<DocumentKeySet> {
240-
const promises: Array<PersistencePromise<void>> = [];
241238
const range = IDBKeyRange.bound(
242239
[targetId],
243240
[targetId + 1],

packages/firestore/src/local/memory_query_cache.ts

-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import { TargetId } from '../core/types';
2020
import { DocumentKeySet } from '../model/collections';
2121
import { DocumentKey } from '../model/document_key';
2222
import { ObjectMap } from '../util/obj_map';
23-
import { SortedSet } from '../util/sorted_set';
2423

2524
import { GarbageCollector } from './garbage_collector';
2625
import { PersistenceTransaction } from './persistence';

packages/firestore/src/local/memory_remote_document_cache.ts

-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import {
2222
} from '../model/collections';
2323
import { Document, MaybeDocument } from '../model/document';
2424
import { DocumentKey } from '../model/document_key';
25-
import { DocumentSet } from '../model/document_set';
2625

2726
import { PersistenceTransaction } from './persistence';
2827
import { PersistencePromise } from './persistence_promise';

packages/firestore/src/local/reference_set.ts

-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import { BatchId, TargetId } from '../core/types';
1818
import { documentKeySet, DocumentKeySet } from '../model/collections';
1919
import { DocumentKey } from '../model/document_key';
20-
import { assert } from '../util/assert';
2120
import { primitiveComparator } from '../util/misc';
2221
import { SortedSet } from '../util/sorted_set';
2322

packages/firestore/src/model/document_set.ts

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { assert } from '../util/assert';
1817
import { SortedMap } from '../util/sorted_map';
1918

2019
import { documentMap } from './collections';

packages/firestore/src/model/field_value.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,8 @@ import { SnapshotOptions } from '../api/database';
2020
import { DatabaseId } from '../core/database_info';
2121
import { Timestamp } from '../core/timestamp';
2222
import { assert, fail } from '../util/assert';
23-
import { AnyJs, primitiveComparator } from '../util/misc';
24-
import * as objUtils from '../util/obj';
23+
import { primitiveComparator } from '../util/misc';
2524
import { SortedMap } from '../util/sorted_map';
26-
import * as typeUtils from '../util/types';
2725

2826
import { DocumentKey } from './document_key';
2927
import { FieldPath } from './path';

packages/firestore/src/platform/config.ts

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
* limitations under the License.
1515
*/
1616

17-
import * as firestore from '@firebase/firestore-types';
1817
import { FirebaseApp, FirebaseNamespace } from '@firebase/app-types';
1918
import { _FirebaseNamespace } from '@firebase/app-types/private';
2019
import { PublicBlob } from '../api/blob';

packages/firestore/src/platform_node/grpc_connection.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import { mapCodeFromRpcCode } from '../remote/rpc_error';
2929
import { assert } from '../util/assert';
3030
import { FirestoreError } from '../util/error';
3131
import * as log from '../util/log';
32-
import { AnyJs } from '../util/misc';
3332
import { NodeCallback, nodePromise } from '../util/node_api';
3433
import { Deferred } from '../util/promise';
3534

@@ -45,7 +44,7 @@ const X_GOOG_API_CLIENT_VALUE = `gl-node/${process.versions.node} fire/${
4544
type DuplexRpc = () => grpc.ClientDuplexStream;
4645
type ReadableRpc<Req> = (req: Req) => grpc.ClientReadableStream;
4746
type UnaryRpc<Req, Resp> = (
48-
req,
47+
req: Req,
4948
callback: (err?: grpc.ServiceError, resp?: Resp) => void
5049
) => grpc.ClientUnaryCall;
5150

packages/firestore/src/remote/datastore.ts

+1-7
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
import * as api from '../protos/firestore_proto_api';
1818
import { CredentialsProvider } from '../api/credentials';
19-
import { DatabaseInfo } from '../core/database_info';
2019
import { maybeDocumentMap } from '../model/collections';
2120
import { MaybeDocument } from '../model/document';
2221
import { DocumentKey } from '../model/document_key';
@@ -27,9 +26,7 @@ import { AsyncQueue } from '../util/async_queue';
2726
import { Connection } from './connection';
2827
import {
2928
PersistentListenStream,
30-
PersistentWriteStream,
31-
WatchStreamListener,
32-
WriteStreamListener
29+
PersistentWriteStream
3330
} from './persistent_stream';
3431
import { JsonProtoSerializer } from './serializer';
3532

@@ -50,7 +47,6 @@ interface CommitRequest extends api.CommitRequest {
5047
*/
5148
export class Datastore {
5249
constructor(
53-
private databaseInfo: DatabaseInfo,
5450
private queue: AsyncQueue,
5551
private connection: Connection,
5652
private credentials: CredentialsProvider,
@@ -60,7 +56,6 @@ export class Datastore {
6056

6157
newPersistentWriteStream(): PersistentWriteStream {
6258
return new PersistentWriteStream(
63-
this.databaseInfo,
6459
this.queue,
6560
this.connection,
6661
this.credentials,
@@ -71,7 +66,6 @@ export class Datastore {
7166

7267
newPersistentWatchStream(): PersistentListenStream {
7368
return new PersistentListenStream(
74-
this.databaseInfo,
7569
this.queue,
7670
this.connection,
7771
this.credentials,

packages/firestore/src/remote/persistent_stream.ts

+25-14
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
import * as api from '../protos/firestore_proto_api';
1818
import { CredentialsProvider, Token } from '../api/credentials';
19-
import { DatabaseInfo } from '../core/database_info';
2019
import { SnapshotVersion } from '../core/snapshot_version';
2120
import { ProtoByteString, TargetId } from '../core/types';
2221
import { QueryData } from '../local/query_data';
@@ -31,6 +30,7 @@ import { Connection, Stream } from './connection';
3130
import { JsonProtoSerializer } from './serializer';
3231
import { WatchChange } from './watch_change';
3332
import { isNullOrUndefined } from '../util/types';
33+
import { CancelablePromise } from '../util/promise';
3434

3535
const LOG_TAG = 'PersistentStream';
3636

@@ -154,7 +154,7 @@ export abstract class PersistentStream<
154154
ListenerType extends PersistentStreamListener
155155
> {
156156
private state: PersistentStreamState;
157-
private idle = false;
157+
private inactivityTimerPromise: CancelablePromise<void> | null = null;
158158
private stream: Stream<SendType, ReceiveType> | null = null;
159159

160160
protected backoff: ExponentialBackoff;
@@ -245,16 +245,25 @@ export abstract class PersistentStream<
245245
}
246246

247247
/**
248-
* Initializes the idle timer. If no write takes place within one minute, the
249-
* WebChannel stream will be closed.
248+
* Marks this stream as idle. If no further actions are performed on the
249+
* stream for one minute, the stream will automatically close itself and
250+
* notify the stream's onClose() handler with Status.OK. The stream will then
251+
* be in a !isStarted() state, requiring the caller to start the stream again
252+
* before further use.
253+
*
254+
* Only streams that are in state 'Open' can be marked idle, as all other
255+
* states imply pending network operations.
250256
*/
251257
markIdle(): void {
252-
this.idle = true;
253-
this.queue
254-
.schedule(() => {
255-
return this.handleIdleCloseTimer();
256-
}, IDLE_TIMEOUT_MS)
257-
.catch((err: FirestoreError) => {
258+
// Starts the idle time if we are in state 'Open' and are not yet already
259+
// running a timer (in which case the previous idle timeout still applies).
260+
if (this.isOpen() && this.inactivityTimerPromise === null) {
261+
this.inactivityTimerPromise = this.queue.scheduleWithDelay(
262+
() => this.handleIdleCloseTimer(),
263+
IDLE_TIMEOUT_MS
264+
);
265+
266+
this.inactivityTimerPromise.catch((err: FirestoreError) => {
258267
// When the AsyncQueue gets drained during testing, pending Promises
259268
// (including these idle checks) will get rejected. We special-case
260269
// these cancelled idle checks to make sure that these specific Promise
@@ -266,6 +275,7 @@ export abstract class PersistentStream<
266275
}`
267276
);
268277
});
278+
}
269279
}
270280

271281
/** Sends a message to the underlying stream. */
@@ -276,7 +286,7 @@ export abstract class PersistentStream<
276286

277287
/** Called by the idle timer when the stream should close due to inactivity. */
278288
private handleIdleCloseTimer(): Promise<void> {
279-
if (this.isOpen() && this.idle) {
289+
if (this.isOpen()) {
280290
// When timing out an idle stream there's no reason to force the stream into backoff when
281291
// it restarts so set the stream state to Initial instead of Error.
282292
return this.close(PersistentStreamState.Initial);
@@ -286,7 +296,10 @@ export abstract class PersistentStream<
286296

287297
/** Marks the stream as active again. */
288298
private cancelIdleCheck() {
289-
this.idle = false;
299+
if (this.inactivityTimerPromise) {
300+
this.inactivityTimerPromise.cancel();
301+
this.inactivityTimerPromise = null;
302+
}
290303
}
291304

292305
/**
@@ -520,7 +533,6 @@ export class PersistentListenStream extends PersistentStream<
520533
WatchStreamListener
521534
> {
522535
constructor(
523-
private databaseInfo: DatabaseInfo,
524536
queue: AsyncQueue,
525537
connection: Connection,
526538
credentials: CredentialsProvider,
@@ -624,7 +636,6 @@ export class PersistentWriteStream extends PersistentStream<
624636
private handshakeComplete_ = false;
625637

626638
constructor(
627-
private databaseInfo: DatabaseInfo,
628639
queue: AsyncQueue,
629640
connection: Connection,
630641
credentials: CredentialsProvider,

packages/firestore/src/remote/remote_store.ts

-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616

1717
import { User } from '../auth/user';
18-
import { DatabaseInfo } from '../core/database_info';
1918
import { SnapshotVersion } from '../core/snapshot_version';
2019
import { Transaction } from '../core/transaction';
2120
import { BatchId, OnlineState, TargetId } from '../core/types';
@@ -31,7 +30,6 @@ import {
3130
} from '../model/mutation_batch';
3231
import { emptyByteString } from '../platform/platform';
3332
import { assert } from '../util/assert';
34-
import { AsyncQueue } from '../util/async_queue';
3533
import { Code, FirestoreError } from '../util/error';
3634
import * as log from '../util/log';
3735
import * as objUtils from '../util/obj';
@@ -291,7 +289,6 @@ export class RemoteStore {
291289
objUtils.contains(this.listenTargets, targetId),
292290
'unlisten called without assigned target ID!'
293291
);
294-
const queryData = this.listenTargets[targetId];
295292
delete this.listenTargets[targetId];
296293
if (this.isNetworkEnabled() && this.watchStream.isOpen()) {
297294
this.sendUnwatchRequest(targetId);

0 commit comments

Comments
 (0)