@firebase/firestore 3.4.4-canary.222f264ff → 3.4.4-canary.2dd99ae2d

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/firestore/src/api/{query.d.ts → filter.d.ts} +0 -0
  2. package/dist/firestore/src/api.d.ts +1 -1
  3. package/dist/firestore/src/core/database_info.d.ts +1 -0
  4. package/dist/firestore/src/core/target.d.ts +26 -1
  5. package/dist/firestore/src/local/local_serializer.d.ts +1 -1
  6. package/dist/firestore/src/local/remote_document_change_buffer.d.ts +3 -12
  7. package/dist/firestore/src/model/document.d.ts +7 -0
  8. package/dist/firestore/src/model/document_key.d.ts +1 -0
  9. package/dist/firestore/src/model/field_index.d.ts +87 -7
  10. package/dist/firestore/src/model/values.d.ts +7 -0
  11. package/dist/firestore/test/unit/local/test_remote_document_cache.d.ts +1 -1
  12. package/dist/firestore/test/unit/model/field_index.test.d.ts +17 -0
  13. package/dist/firestore/test/unit/model/target.test.d.ts +17 -0
  14. package/dist/firestore/test/util/helpers.d.ts +8 -2
  15. package/dist/index.esm2017.js +3300 -3205
  16. package/dist/index.esm2017.js.map +1 -1
  17. package/dist/index.esm5.js +3646 -3587
  18. package/dist/index.esm5.js.map +1 -1
  19. package/dist/index.node.cjs.js +266 -150
  20. package/dist/index.node.cjs.js.map +1 -1
  21. package/dist/index.node.mjs +266 -150
  22. package/dist/index.node.mjs.map +1 -1
  23. package/dist/index.rn.js +3299 -3246
  24. package/dist/index.rn.js.map +1 -1
  25. package/dist/internal.d.ts +12 -12
  26. package/dist/lite/firestore/src/api/{query.d.ts → filter.d.ts} +0 -0
  27. package/dist/lite/firestore/src/api.d.ts +1 -1
  28. package/dist/lite/firestore/src/core/database_info.d.ts +1 -0
  29. package/dist/lite/firestore/src/core/target.d.ts +26 -1
  30. package/dist/lite/firestore/src/local/local_serializer.d.ts +1 -1
  31. package/dist/lite/firestore/src/local/remote_document_change_buffer.d.ts +3 -12
  32. package/dist/lite/firestore/src/model/document.d.ts +7 -0
  33. package/dist/lite/firestore/src/model/document_key.d.ts +1 -0
  34. package/dist/lite/firestore/src/model/field_index.d.ts +87 -7
  35. package/dist/lite/firestore/src/model/values.d.ts +7 -0
  36. package/dist/lite/firestore/test/unit/local/test_remote_document_cache.d.ts +1 -1
  37. package/dist/lite/firestore/test/unit/model/field_index.test.d.ts +17 -0
  38. package/dist/lite/firestore/test/unit/model/target.test.d.ts +17 -0
  39. package/dist/lite/firestore/test/util/helpers.d.ts +8 -2
  40. package/dist/lite/index.browser.esm2017.js +20 -9
  41. package/dist/lite/index.browser.esm2017.js.map +1 -1
  42. package/dist/lite/index.browser.esm5.js +49 -42
  43. package/dist/lite/index.browser.esm5.js.map +1 -1
  44. package/dist/lite/index.node.cjs.js +20 -8
  45. package/dist/lite/index.node.cjs.js.map +1 -1
  46. package/dist/lite/index.node.mjs +20 -8
  47. package/dist/lite/index.node.mjs.map +1 -1
  48. package/dist/lite/index.rn.esm2017.js +20 -9
  49. package/dist/lite/index.rn.esm2017.js.map +1 -1
  50. package/dist/lite/internal.d.ts +9 -0
  51. package/dist/lite/packages/firestore/dist/lite/index.browser.esm2017.d.ts +1 -0
  52. package/dist/lite/packages/firestore/src/api/{query.d.ts → filter.d.ts} +0 -0
  53. package/dist/lite/packages/firestore/src/api.d.ts +1 -1
  54. package/dist/lite/packages/firestore/src/core/database_info.d.ts +1 -0
  55. package/dist/lite/packages/firestore/src/core/target.d.ts +26 -1
  56. package/dist/lite/packages/firestore/src/local/local_serializer.d.ts +1 -1
  57. package/dist/lite/packages/firestore/src/local/remote_document_change_buffer.d.ts +3 -12
  58. package/dist/lite/packages/firestore/src/model/document.d.ts +7 -0
  59. package/dist/lite/packages/firestore/src/model/document_key.d.ts +1 -0
  60. package/dist/lite/packages/firestore/src/model/field_index.d.ts +87 -7
  61. package/dist/lite/packages/firestore/src/model/values.d.ts +7 -0
  62. package/dist/lite/packages/firestore/test/unit/local/test_remote_document_cache.d.ts +1 -1
  63. package/dist/lite/packages/firestore/test/unit/model/field_index.test.d.ts +17 -0
  64. package/dist/lite/packages/firestore/test/unit/model/target.test.d.ts +17 -0
  65. package/dist/lite/packages/firestore/test/util/helpers.d.ts +8 -2
  66. package/dist/lite/private.d.ts +7 -0
  67. package/dist/packages/firestore/dist/index.esm2017.d.ts +183 -181
  68. package/dist/packages/firestore/src/api/{query.d.ts → filter.d.ts} +0 -0
  69. package/dist/packages/firestore/src/api.d.ts +1 -1
  70. package/dist/packages/firestore/src/core/database_info.d.ts +1 -0
  71. package/dist/packages/firestore/src/core/target.d.ts +26 -1
  72. package/dist/packages/firestore/src/local/local_serializer.d.ts +1 -1
  73. package/dist/packages/firestore/src/local/remote_document_change_buffer.d.ts +3 -12
  74. package/dist/packages/firestore/src/model/document.d.ts +7 -0
  75. package/dist/packages/firestore/src/model/document_key.d.ts +1 -0
  76. package/dist/packages/firestore/src/model/field_index.d.ts +87 -7
  77. package/dist/packages/firestore/src/model/values.d.ts +7 -0
  78. package/dist/packages/firestore/test/unit/local/test_remote_document_cache.d.ts +1 -1
  79. package/dist/packages/firestore/test/unit/model/field_index.test.d.ts +17 -0
  80. package/dist/packages/firestore/test/unit/model/target.test.d.ts +17 -0
  81. package/dist/packages/firestore/test/util/helpers.d.ts +8 -2
  82. package/dist/private.d.ts +10 -12
  83. package/package.json +9 -9
@@ -8,7 +8,7 @@ import { credentials, loadPackageDefinition, Metadata } from '@grpc/grpc-js';
8
8
  import { fromJSON } from '@grpc/proto-loader';
9
9
 
10
10
  const name = "@firebase/firestore";
11
- const version$1 = "3.4.4-canary.222f264ff";
11
+ const version$1 = "3.4.4-canary.2dd99ae2d";
12
12
 
13
13
  /**
14
14
  * @license
@@ -61,7 +61,7 @@ User.GOOGLE_CREDENTIALS = new User('google-credentials-uid');
61
61
  User.FIRST_PARTY = new User('first-party-uid');
62
62
  User.MOCK_USER = new User('mock-user');
63
63
 
64
- const version = "9.6.5-canary.222f264ff";
64
+ const version = "9.6.5-canary.2dd99ae2d";
65
65
 
66
66
  /**
67
67
  * @license
@@ -3374,6 +3374,75 @@ function getLocalWriteTime(value) {
3374
3374
  return new Timestamp(localWriteTime.seconds, localWriteTime.nanos);
3375
3375
  }
3376
3376
 
3377
+ /**
3378
+ * @license
3379
+ * Copyright 2017 Google LLC
3380
+ *
3381
+ * Licensed under the Apache License, Version 2.0 (the "License");
3382
+ * you may not use this file except in compliance with the License.
3383
+ * You may obtain a copy of the License at
3384
+ *
3385
+ * http://www.apache.org/licenses/LICENSE-2.0
3386
+ *
3387
+ * Unless required by applicable law or agreed to in writing, software
3388
+ * distributed under the License is distributed on an "AS IS" BASIS,
3389
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3390
+ * See the License for the specific language governing permissions and
3391
+ * limitations under the License.
3392
+ */
3393
+ class DatabaseInfo {
3394
+ /**
3395
+ * Constructs a DatabaseInfo using the provided host, databaseId and
3396
+ * persistenceKey.
3397
+ *
3398
+ * @param databaseId - The database to use.
3399
+ * @param appId - The Firebase App Id.
3400
+ * @param persistenceKey - A unique identifier for this Firestore's local
3401
+ * storage (used in conjunction with the databaseId).
3402
+ * @param host - The Firestore backend host to connect to.
3403
+ * @param ssl - Whether to use SSL when connecting.
3404
+ * @param forceLongPolling - Whether to use the forceLongPolling option
3405
+ * when using WebChannel as the network transport.
3406
+ * @param autoDetectLongPolling - Whether to use the detectBufferingProxy
3407
+ * option when using WebChannel as the network transport.
3408
+ * @param useFetchStreams Whether to use the Fetch API instead of
3409
+ * XMLHTTPRequest
3410
+ */
3411
+ constructor(databaseId, appId, persistenceKey, host, ssl, forceLongPolling, autoDetectLongPolling, useFetchStreams) {
3412
+ this.databaseId = databaseId;
3413
+ this.appId = appId;
3414
+ this.persistenceKey = persistenceKey;
3415
+ this.host = host;
3416
+ this.ssl = ssl;
3417
+ this.forceLongPolling = forceLongPolling;
3418
+ this.autoDetectLongPolling = autoDetectLongPolling;
3419
+ this.useFetchStreams = useFetchStreams;
3420
+ }
3421
+ }
3422
+ /** The default database name for a project. */
3423
+ const DEFAULT_DATABASE_NAME = '(default)';
3424
+ /**
3425
+ * Represents the database ID a Firestore client is associated with.
3426
+ * @internal
3427
+ */
3428
+ class DatabaseId {
3429
+ constructor(projectId, database) {
3430
+ this.projectId = projectId;
3431
+ this.database = database ? database : DEFAULT_DATABASE_NAME;
3432
+ }
3433
+ static empty() {
3434
+ return new DatabaseId('', '');
3435
+ }
3436
+ get isDefaultDatabase() {
3437
+ return this.database === DEFAULT_DATABASE_NAME;
3438
+ }
3439
+ isEqual(other) {
3440
+ return (other instanceof DatabaseId &&
3441
+ other.projectId === this.projectId &&
3442
+ other.database === this.database);
3443
+ }
3444
+ }
3445
+
3377
3446
  /**
3378
3447
  * @license
3379
3448
  * Copyright 2017 Google LLC
@@ -3445,6 +3514,9 @@ class DocumentKey {
3445
3514
  static fromName(name) {
3446
3515
  return new DocumentKey(ResourcePath.fromString(name).popFirst(5));
3447
3516
  }
3517
+ static empty() {
3518
+ return new DocumentKey(ResourcePath.emptyPath());
3519
+ }
3448
3520
  /** Returns true if the document is in the specified collectionId. */
3449
3521
  hasCollectionId(collectionId) {
3450
3522
  return (this.path.length >= 2 &&
@@ -4093,10 +4165,11 @@ function extractFieldMask(value) {
4093
4165
  * from all views.
4094
4166
  */
4095
4167
  class MutableDocument {
4096
- constructor(key, documentType, version, data, documentState) {
4168
+ constructor(key, documentType, version, readTime, data, documentState) {
4097
4169
  this.key = key;
4098
4170
  this.documentType = documentType;
4099
4171
  this.version = version;
4172
+ this.readTime = readTime;
4100
4173
  this.data = data;
4101
4174
  this.documentState = documentState;
4102
4175
  }
@@ -4105,18 +4178,18 @@ class MutableDocument {
4105
4178
  * base document for mutations.
4106
4179
  */
4107
4180
  static newInvalidDocument(documentKey) {
4108
- return new MutableDocument(documentKey, 0 /* INVALID */, SnapshotVersion.min(), ObjectValue.empty(), 0 /* SYNCED */);
4181
+ return new MutableDocument(documentKey, 0 /* INVALID */, SnapshotVersion.min(), SnapshotVersion.min(), ObjectValue.empty(), 0 /* SYNCED */);
4109
4182
  }
4110
4183
  /**
4111
4184
  * Creates a new document that is known to exist with the given data at the
4112
4185
  * given version.
4113
4186
  */
4114
4187
  static newFoundDocument(documentKey, version, value) {
4115
- return new MutableDocument(documentKey, 1 /* FOUND_DOCUMENT */, version, value, 0 /* SYNCED */);
4188
+ return new MutableDocument(documentKey, 1 /* FOUND_DOCUMENT */, version, SnapshotVersion.min(), value, 0 /* SYNCED */);
4116
4189
  }
4117
4190
  /** Creates a new document that is known to not exist at the given version. */
4118
4191
  static newNoDocument(documentKey, version) {
4119
- return new MutableDocument(documentKey, 2 /* NO_DOCUMENT */, version, ObjectValue.empty(), 0 /* SYNCED */);
4192
+ return new MutableDocument(documentKey, 2 /* NO_DOCUMENT */, version, SnapshotVersion.min(), ObjectValue.empty(), 0 /* SYNCED */);
4120
4193
  }
4121
4194
  /**
4122
4195
  * Creates a new document that is known to exist at the given version but
@@ -4124,7 +4197,7 @@ class MutableDocument {
4124
4197
  * base document).
4125
4198
  */
4126
4199
  static newUnknownDocument(documentKey, version) {
4127
- return new MutableDocument(documentKey, 3 /* UNKNOWN_DOCUMENT */, version, ObjectValue.empty(), 2 /* HAS_COMMITTED_MUTATIONS */);
4200
+ return new MutableDocument(documentKey, 3 /* UNKNOWN_DOCUMENT */, version, SnapshotVersion.min(), ObjectValue.empty(), 2 /* HAS_COMMITTED_MUTATIONS */);
4128
4201
  }
4129
4202
  /**
4130
4203
  * Changes the document type to indicate that it exists and that its version
@@ -4168,6 +4241,10 @@ class MutableDocument {
4168
4241
  this.documentState = 1 /* HAS_LOCAL_MUTATIONS */;
4169
4242
  return this;
4170
4243
  }
4244
+ setReadTime(readTime) {
4245
+ this.readTime = readTime;
4246
+ return this;
4247
+ }
4171
4248
  get hasLocalMutations() {
4172
4249
  return this.documentState === 1 /* HAS_LOCAL_MUTATIONS */;
4173
4250
  }
@@ -4198,7 +4275,7 @@ class MutableDocument {
4198
4275
  this.data.isEqual(other.data));
4199
4276
  }
4200
4277
  mutableCopy() {
4201
- return new MutableDocument(this.key, this.documentType, this.version, this.data.clone(), this.documentState);
4278
+ return new MutableDocument(this.key, this.documentType, this.version, this.readTime, this.data.clone(), this.documentState);
4202
4279
  }
4203
4280
  toString() {
4204
4281
  return (`Document(${this.key}, ${this.version}, ${JSON.stringify(this.data.value)}, ` +
@@ -4221,6 +4298,125 @@ function compareDocumentsByField(field, d1, d2) {
4221
4298
  }
4222
4299
  }
4223
4300
 
4301
+ /**
4302
+ * @license
4303
+ * Copyright 2021 Google LLC
4304
+ *
4305
+ * Licensed under the Apache License, Version 2.0 (the "License");
4306
+ * you may not use this file except in compliance with the License.
4307
+ * You may obtain a copy of the License at
4308
+ *
4309
+ * http://www.apache.org/licenses/LICENSE-2.0
4310
+ *
4311
+ * Unless required by applicable law or agreed to in writing, software
4312
+ * distributed under the License is distributed on an "AS IS" BASIS,
4313
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4314
+ * See the License for the specific language governing permissions and
4315
+ * limitations under the License.
4316
+ */
4317
+ /**
4318
+ * The initial mutation batch id for each index. Gets updated during index
4319
+ * backfill.
4320
+ */
4321
+ const INITIAL_LARGEST_BATCH_ID = -1;
4322
+ /**
4323
+ * The initial sequence number for each index. Gets updated during index
4324
+ * backfill.
4325
+ */
4326
+ const INITIAL_SEQUENCE_NUMBER = 0;
4327
+ /**
4328
+ * An index definition for field indexes in Firestore.
4329
+ *
4330
+ * Every index is associated with a collection. The definition contains a list
4331
+ * of fields and their index kind (which can be `ASCENDING`, `DESCENDING` or
4332
+ * `CONTAINS` for ArrayContains/ArrayContainsAny queries).
4333
+ *
4334
+ * Unlike the backend, the SDK does not differentiate between collection or
4335
+ * collection group-scoped indices. Every index can be used for both single
4336
+ * collection and collection group queries.
4337
+ */
4338
+ class FieldIndex {
4339
+ constructor(
4340
+ /**
4341
+ * The index ID. Returns -1 if the index ID is not available (e.g. the index
4342
+ * has not yet been persisted).
4343
+ */
4344
+ indexId,
4345
+ /** The collection ID this index applies to. */
4346
+ collectionGroup,
4347
+ /** The field segments for this index. */
4348
+ segments,
4349
+ /** Shows how up-to-date the index is for the current user. */
4350
+ indexState) {
4351
+ this.indexId = indexId;
4352
+ this.collectionGroup = collectionGroup;
4353
+ this.segments = segments;
4354
+ this.indexState = indexState;
4355
+ }
4356
+ }
4357
+ /** An ID for an index that has not yet been added to persistence. */
4358
+ FieldIndex.UNKNOWN_ID = -1;
4359
+ /** An index component consisting of field path and index type. */
4360
+ class IndexSegment {
4361
+ constructor(
4362
+ /** The field path of the component. */
4363
+ fieldPath,
4364
+ /** The fields sorting order. */
4365
+ kind) {
4366
+ this.fieldPath = fieldPath;
4367
+ this.kind = kind;
4368
+ }
4369
+ }
4370
+ /**
4371
+ * Stores the "high water mark" that indicates how updated the Index is for the
4372
+ * current user.
4373
+ */
4374
+ class IndexState {
4375
+ constructor(
4376
+ /**
4377
+ * Indicates when the index was last updated (relative to other indexes).
4378
+ */
4379
+ sequenceNumber,
4380
+ /** The the latest indexed read time, document and batch id. */
4381
+ offset) {
4382
+ this.sequenceNumber = sequenceNumber;
4383
+ this.offset = offset;
4384
+ }
4385
+ /** The state of an index that has not yet been backfilled. */
4386
+ static empty() {
4387
+ return new IndexState(INITIAL_SEQUENCE_NUMBER, IndexOffset.min());
4388
+ }
4389
+ }
4390
+ /**
4391
+ * Stores the latest read time, document and batch ID that were processed for an
4392
+ * index.
4393
+ */
4394
+ class IndexOffset {
4395
+ constructor(
4396
+ /**
4397
+ * The latest read time version that has been indexed by Firestore for this
4398
+ * field index.
4399
+ */
4400
+ readTime,
4401
+ /**
4402
+ * The key of the last document that was indexed for this query. Use
4403
+ * `DocumentKey.empty()` if no document has been indexed.
4404
+ */
4405
+ documentKey,
4406
+ /*
4407
+ * The largest mutation batch id that's been processed by Firestore.
4408
+ */
4409
+ largestBatchId) {
4410
+ this.readTime = readTime;
4411
+ this.documentKey = documentKey;
4412
+ this.largestBatchId = largestBatchId;
4413
+ }
4414
+ /** The state of an index that has not yet been backfilled. */
4415
+ static min() {
4416
+ return new IndexOffset(SnapshotVersion.min(), DocumentKey.empty(), INITIAL_LARGEST_BATCH_ID);
4417
+ }
4418
+ }
4419
+
4224
4420
  /**
4225
4421
  * @license
4226
4422
  * Copyright 2019 Google LLC
@@ -4345,7 +4541,7 @@ function targetEquals(left, right) {
4345
4541
  }
4346
4542
  return boundEquals(left.endAt, right.endAt);
4347
4543
  }
4348
- function isDocumentTarget(target) {
4544
+ function targetIsDocumentTarget(target) {
4349
4545
  return (DocumentKey.isDocumentKey(target.path) &&
4350
4546
  target.collectionGroup === null &&
4351
4547
  target.filters.length === 0);
@@ -4533,6 +4729,7 @@ class ArrayContainsAnyFilter extends FieldFilter {
4533
4729
  return other.arrayValue.values.some(val => arrayValueContains(this.value.arrayValue, val));
4534
4730
  }
4535
4731
  }
4732
+ // TODO(indexing): Change Bound.before to "inclusive"
4536
4733
  /**
4537
4734
  * Represents a bound of a query.
4538
4735
  *
@@ -6990,7 +7187,7 @@ class WatchChangeAggregator {
6990
7187
  const targetData = this.targetDataForActiveTarget(targetId);
6991
7188
  if (targetData) {
6992
7189
  const target = targetData.target;
6993
- if (isDocumentTarget(target)) {
7190
+ if (targetIsDocumentTarget(target)) {
6994
7191
  if (expectedCount === 0) {
6995
7192
  // The existence filter told us the document does not exist. We deduce
6996
7193
  // that this document does not exist and apply a deleted document to
@@ -7025,7 +7222,7 @@ class WatchChangeAggregator {
7025
7222
  this.targetStates.forEach((targetState, targetId) => {
7026
7223
  const targetData = this.targetDataForActiveTarget(targetId);
7027
7224
  if (targetData) {
7028
- if (targetState.current && isDocumentTarget(targetData.target)) {
7225
+ if (targetState.current && targetIsDocumentTarget(targetData.target)) {
7029
7226
  // Document queries for document that don't exist can produce an empty
7030
7227
  // result set. To update our local cache, we synthesize a document
7031
7228
  // delete if we have not previously received the document. This
@@ -7068,6 +7265,7 @@ class WatchChangeAggregator {
7068
7265
  resolvedLimboDocuments = resolvedLimboDocuments.add(key);
7069
7266
  }
7070
7267
  });
7268
+ this.pendingDocumentUpdates.forEach((_, doc) => doc.setReadTime(snapshotVersion));
7071
7269
  const remoteEvent = new RemoteEvent(snapshotVersion, targetChanges, this.pendingTargetResets, this.pendingDocumentUpdates, resolvedLimboDocuments);
7072
7270
  this.pendingDocumentUpdates = mutableDocumentMap();
7073
7271
  this.pendingDocumentTargetMapping = documentTargetMap();
@@ -7860,7 +8058,7 @@ function toLabel(serializer, purpose) {
7860
8058
  function toTarget(serializer, targetData) {
7861
8059
  let result;
7862
8060
  const target = targetData.target;
7863
- if (isDocumentTarget(target)) {
8061
+ if (targetIsDocumentTarget(target)) {
7864
8062
  result = { documents: toDocumentsTarget(serializer, target) };
7865
8063
  }
7866
8064
  else {
@@ -8188,29 +8386,34 @@ class LocalSerializer {
8188
8386
  }
8189
8387
  /** Decodes a remote document from storage locally to a Document. */
8190
8388
  function fromDbRemoteDocument(localSerializer, remoteDoc) {
8389
+ let doc;
8191
8390
  if (remoteDoc.document) {
8192
- return fromDocument(localSerializer.remoteSerializer, remoteDoc.document, !!remoteDoc.hasCommittedMutations);
8391
+ doc = fromDocument(localSerializer.remoteSerializer, remoteDoc.document, !!remoteDoc.hasCommittedMutations);
8193
8392
  }
8194
8393
  else if (remoteDoc.noDocument) {
8195
8394
  const key = DocumentKey.fromSegments(remoteDoc.noDocument.path);
8196
8395
  const version = fromDbTimestamp(remoteDoc.noDocument.readTime);
8197
- const document = MutableDocument.newNoDocument(key, version);
8198
- return remoteDoc.hasCommittedMutations
8199
- ? document.setHasCommittedMutations()
8200
- : document;
8396
+ doc = MutableDocument.newNoDocument(key, version);
8397
+ if (remoteDoc.hasCommittedMutations) {
8398
+ doc.setHasCommittedMutations();
8399
+ }
8201
8400
  }
8202
8401
  else if (remoteDoc.unknownDocument) {
8203
8402
  const key = DocumentKey.fromSegments(remoteDoc.unknownDocument.path);
8204
8403
  const version = fromDbTimestamp(remoteDoc.unknownDocument.version);
8205
- return MutableDocument.newUnknownDocument(key, version);
8404
+ doc = MutableDocument.newUnknownDocument(key, version);
8206
8405
  }
8207
8406
  else {
8208
8407
  return fail();
8209
8408
  }
8409
+ if (remoteDoc.readTime) {
8410
+ doc.setReadTime(fromDbTimestampKey(remoteDoc.readTime));
8411
+ }
8412
+ return doc;
8210
8413
  }
8211
8414
  /** Encodes a document for storage locally. */
8212
- function toDbRemoteDocument(localSerializer, document, readTime) {
8213
- const dbReadTime = toDbTimestampKey(readTime);
8415
+ function toDbRemoteDocument(localSerializer, document) {
8416
+ const dbReadTime = toDbTimestampKey(document.readTime);
8214
8417
  const parentPath = document.key.path.popLast().toArray();
8215
8418
  if (document.isFoundDocument()) {
8216
8419
  const doc = toDocument(localSerializer.remoteSerializer, document);
@@ -8221,10 +8424,10 @@ function toDbRemoteDocument(localSerializer, document, readTime) {
8221
8424
  }
8222
8425
  else if (document.isNoDocument()) {
8223
8426
  const path = document.key.path.toArray();
8224
- const readTime = toDbTimestamp(document.version);
8427
+ const version = toDbTimestamp(document.version);
8225
8428
  const hasCommittedMutations = document.hasCommittedMutations;
8226
8429
  return new DbRemoteDocument(
8227
- /* unknownDocument= */ null, new DbNoDocument(path, readTime),
8430
+ /* unknownDocument= */ null, new DbNoDocument(path, version),
8228
8431
  /* document= */ null, hasCommittedMutations, dbReadTime, parentPath);
8229
8432
  }
8230
8433
  else if (document.isUnknownDocument()) {
@@ -8305,7 +8508,7 @@ function toDbTarget(localSerializer, targetData) {
8305
8508
  const dbTimestamp = toDbTimestamp(targetData.snapshotVersion);
8306
8509
  const dbLastLimboFreeTimestamp = toDbTimestamp(targetData.lastLimboFreeSnapshotVersion);
8307
8510
  let queryProto;
8308
- if (isDocumentTarget(targetData.target)) {
8511
+ if (targetIsDocumentTarget(targetData.target)) {
8309
8512
  queryProto = toDocumentsTarget(localSerializer.remoteSerializer, targetData.target);
8310
8513
  }
8311
8514
  else {
@@ -9753,7 +9956,7 @@ class IndexedDbLruDelegateImpl {
9753
9956
  // Our size accounting requires us to read all documents before
9754
9957
  // removing them.
9755
9958
  return changeBuffer.getEntry(txn, docKey).next(() => {
9756
- changeBuffer.removeEntry(docKey);
9959
+ changeBuffer.removeEntry(docKey, SnapshotVersion.min());
9757
9960
  return documentTargetStore(txn).delete(sentinelKey$1(docKey));
9758
9961
  });
9759
9962
  }
@@ -9966,27 +10169,19 @@ class ObjectMap {
9966
10169
  */
9967
10170
  class RemoteDocumentChangeBuffer {
9968
10171
  constructor() {
9969
- // A mapping of document key to the new cache entry that should be written (or null if any
9970
- // existing cache entry should be removed).
10172
+ // A mapping of document key to the new cache entry that should be written.
9971
10173
  this.changes = new ObjectMap(key => key.toString(), (l, r) => l.isEqual(r));
9972
10174
  this.changesApplied = false;
9973
10175
  }
9974
- getReadTime(key) {
9975
- const change = this.changes.get(key);
9976
- if (change) {
9977
- return change.readTime;
9978
- }
9979
- return SnapshotVersion.min();
9980
- }
9981
10176
  /**
9982
10177
  * Buffers a `RemoteDocumentCache.addEntry()` call.
9983
10178
  *
9984
10179
  * You can only modify documents that have already been retrieved via
9985
10180
  * `getEntry()/getEntries()` (enforced via IndexedDbs `apply()`).
9986
10181
  */
9987
- addEntry(document, readTime) {
10182
+ addEntry(document) {
9988
10183
  this.assertNotApplied();
9989
- this.changes.set(document.key, { document, readTime });
10184
+ this.changes.set(document.key, document);
9990
10185
  }
9991
10186
  /**
9992
10187
  * Buffers a `RemoteDocumentCache.removeEntry()` call.
@@ -9994,12 +10189,9 @@ class RemoteDocumentChangeBuffer {
9994
10189
  * You can only remove documents that have already been retrieved via
9995
10190
  * `getEntry()/getEntries()` (enforced via IndexedDbs `apply()`).
9996
10191
  */
9997
- removeEntry(key, readTime = null) {
10192
+ removeEntry(key, readTime) {
9998
10193
  this.assertNotApplied();
9999
- this.changes.set(key, {
10000
- document: MutableDocument.newInvalidDocument(key),
10001
- readTime
10002
- });
10194
+ this.changes.set(key, MutableDocument.newInvalidDocument(key).setReadTime(readTime));
10003
10195
  }
10004
10196
  /**
10005
10197
  * Looks up an entry in the cache. The buffered changes will first be checked,
@@ -10016,7 +10208,7 @@ class RemoteDocumentChangeBuffer {
10016
10208
  this.assertNotApplied();
10017
10209
  const bufferedEntry = this.changes.get(documentKey);
10018
10210
  if (bufferedEntry !== undefined) {
10019
- return PersistencePromise.resolve(bufferedEntry.document);
10211
+ return PersistencePromise.resolve(bufferedEntry);
10020
10212
  }
10021
10213
  else {
10022
10214
  return this.getFromCache(transaction, documentKey);
@@ -10227,7 +10419,7 @@ class IndexedDbRemoteDocumentCacheImpl {
10227
10419
  if (key.length !== immediateChildrenPathLength) {
10228
10420
  return;
10229
10421
  }
10230
- const document = fromDbRemoteDocument(this.serializer, dbRemoteDoc);
10422
+ const document = this.maybeDecodeDocument(DocumentKey.fromSegments(key), dbRemoteDoc);
10231
10423
  if (!query.path.isPrefixOf(document.key.path)) {
10232
10424
  control.done();
10233
10425
  }
@@ -10255,8 +10447,8 @@ class IndexedDbRemoteDocumentCacheImpl {
10255
10447
  return documentGlobalStore(txn).put(DbRemoteDocumentGlobal.key, metadata);
10256
10448
  }
10257
10449
  /**
10258
- * Decodes `remoteDoc` and returns the document (or null, if the document
10259
- * corresponds to the format used for sentinel deletes).
10450
+ * Decodes `dbRemoteDoc` and returns the document (or an invalid document if
10451
+ * the document corresponds to the format used for sentinel deletes).
10260
10452
  */
10261
10453
  maybeDecodeDocument(documentKey, dbRemoteDoc) {
10262
10454
  if (dbRemoteDoc) {
@@ -10350,8 +10542,8 @@ class IndexedDbRemoteDocumentChangeBuffer extends RemoteDocumentChangeBuffer {
10350
10542
  let collectionParents = new SortedSet((l, r) => primitiveComparator(l.canonicalString(), r.canonicalString()));
10351
10543
  this.changes.forEach((key, documentChange) => {
10352
10544
  const previousSize = this.documentSizes.get(key);
10353
- if (documentChange.document.isValidDocument()) {
10354
- const doc = toDbRemoteDocument(this.documentCache.serializer, documentChange.document, this.getReadTime(key));
10545
+ if (documentChange.isValidDocument()) {
10546
+ const doc = toDbRemoteDocument(this.documentCache.serializer, documentChange);
10355
10547
  collectionParents = collectionParents.add(key.path.popLast());
10356
10548
  const size = dbDocumentSize(doc);
10357
10549
  sizeDelta += size - previousSize;
@@ -10364,7 +10556,7 @@ class IndexedDbRemoteDocumentChangeBuffer extends RemoteDocumentChangeBuffer {
10364
10556
  // RemoteDocumentCache. This entry is represented by a NoDocument
10365
10557
  // with a version of 0 and ignored by `maybeDecodeDocument()` but
10366
10558
  // preserved in `getNewDocumentChanges()`.
10367
- const deletedDoc = toDbRemoteDocument(this.documentCache.serializer, MutableDocument.newNoDocument(key, SnapshotVersion.min()), this.getReadTime(key));
10559
+ const deletedDoc = toDbRemoteDocument(this.documentCache.serializer, documentChange.convertToNoDocument(SnapshotVersion.min()));
10368
10560
  promises.push(this.documentCache.addEntry(transaction, key, deletedDoc));
10369
10561
  }
10370
10562
  else {
@@ -11951,14 +12143,14 @@ function localStoreApplyRemoteEventToLocalCache(localStore, remoteEvent) {
11951
12143
  }
11952
12144
  });
11953
12145
  let changedDocs = mutableDocumentMap();
11954
- remoteEvent.documentUpdates.forEach((key, doc) => {
12146
+ remoteEvent.documentUpdates.forEach(key => {
11955
12147
  if (remoteEvent.resolvedLimboDocuments.has(key)) {
11956
12148
  promises.push(localStoreImpl.persistence.referenceDelegate.updateLimboDocument(txn, key));
11957
12149
  }
11958
12150
  });
11959
12151
  // Each loop iteration only affects its "own" doc, so it's safe to get all the remote
11960
12152
  // documents in advance in a single call.
11961
- promises.push(populateDocumentChangeBuffer(txn, documentBuffer, remoteEvent.documentUpdates, remoteVersion, undefined).next(result => {
12153
+ promises.push(populateDocumentChangeBuffer(txn, documentBuffer, remoteEvent.documentUpdates).next(result => {
11962
12154
  changedDocs = result;
11963
12155
  }));
11964
12156
  // HACK: The only reason we allow a null snapshot version is so that we
@@ -11999,17 +12191,13 @@ function localStoreApplyRemoteEventToLocalCache(localStore, remoteEvent) {
11999
12191
  * Note: this function will use `documentVersions` if it is defined;
12000
12192
  * when it is not defined, resorts to `globalVersion`.
12001
12193
  */
12002
- function populateDocumentChangeBuffer(txn, documentBuffer, documents, globalVersion,
12003
- // TODO(wuandy): We could add `readTime` to MaybeDocument instead to remove
12004
- // this parameter.
12005
- documentVersions) {
12194
+ function populateDocumentChangeBuffer(txn, documentBuffer, documents) {
12006
12195
  let updatedKeys = documentKeySet();
12007
12196
  documents.forEach(k => (updatedKeys = updatedKeys.add(k)));
12008
12197
  return documentBuffer.getEntries(txn, updatedKeys).next(existingDocs => {
12009
12198
  let changedDocs = mutableDocumentMap();
12010
12199
  documents.forEach((key, doc) => {
12011
12200
  const existingDoc = existingDocs.get(key);
12012
- const docReadTime = (documentVersions === null || documentVersions === void 0 ? void 0 : documentVersions.get(key)) || globalVersion;
12013
12201
  // Note: The order of the steps below is important, since we want
12014
12202
  // to ensure that rejected limbo resolutions (which fabricate
12015
12203
  // NoDocuments with SnapshotVersion.min()) never add documents to
@@ -12018,14 +12206,14 @@ documentVersions) {
12018
12206
  // NoDocuments with SnapshotVersion.min() are used in manufactured
12019
12207
  // events. We remove these documents from cache since we lost
12020
12208
  // access.
12021
- documentBuffer.removeEntry(key, docReadTime);
12209
+ documentBuffer.removeEntry(key, doc.readTime);
12022
12210
  changedDocs = changedDocs.insert(key, doc);
12023
12211
  }
12024
12212
  else if (!existingDoc.isValidDocument() ||
12025
12213
  doc.version.compareTo(existingDoc.version) > 0 ||
12026
12214
  (doc.version.compareTo(existingDoc.version) === 0 &&
12027
12215
  existingDoc.hasPendingWrites)) {
12028
- documentBuffer.addEntry(doc, docReadTime);
12216
+ documentBuffer.addEntry(doc);
12029
12217
  changedDocs = changedDocs.insert(key, doc);
12030
12218
  }
12031
12219
  else {
@@ -12279,7 +12467,8 @@ function applyWriteToRemoteDocuments(localStoreImpl, txn, batchResult, documentB
12279
12467
  // We use the commitVersion as the readTime rather than the
12280
12468
  // document's updateTime since the updateTime is not advanced
12281
12469
  // for updates that do not modify the underlying document.
12282
- documentBuffer.addEntry(doc, batchResult.commitVersion);
12470
+ doc.setReadTime(batchResult.commitVersion);
12471
+ documentBuffer.addEntry(doc);
12283
12472
  }
12284
12473
  }
12285
12474
  });
@@ -12380,14 +12569,14 @@ async function localStoreApplyBundledDocuments(localStore, bundleConverter, docu
12380
12569
  const localStoreImpl = debugCast(localStore);
12381
12570
  let documentKeys = documentKeySet();
12382
12571
  let documentMap = mutableDocumentMap();
12383
- let versionMap = documentVersionMap();
12384
12572
  for (const bundleDoc of documents) {
12385
12573
  const documentKey = bundleConverter.toDocumentKey(bundleDoc.metadata.name);
12386
12574
  if (bundleDoc.document) {
12387
12575
  documentKeys = documentKeys.add(documentKey);
12388
12576
  }
12389
- documentMap = documentMap.insert(documentKey, bundleConverter.toMutableDocument(bundleDoc));
12390
- versionMap = versionMap.insert(documentKey, bundleConverter.toSnapshotVersion(bundleDoc.metadata.readTime));
12577
+ const doc = bundleConverter.toMutableDocument(bundleDoc);
12578
+ doc.setReadTime(bundleConverter.toSnapshotVersion(bundleDoc.metadata.readTime));
12579
+ documentMap = documentMap.insert(documentKey, doc);
12391
12580
  }
12392
12581
  const documentBuffer = localStoreImpl.remoteDocuments.newChangeBuffer({
12393
12582
  trackRemovals: true // Make sure document removals show up in `getNewDocumentChanges()`
@@ -12396,7 +12585,7 @@ async function localStoreApplyBundledDocuments(localStore, bundleConverter, docu
12396
12585
  // they will not get garbage collected right away.
12397
12586
  const umbrellaTargetData = await localStoreAllocateTarget(localStoreImpl, umbrellaTarget(bundleName));
12398
12587
  return localStoreImpl.persistence.runTransaction('Apply bundle documents', 'readwrite', txn => {
12399
- return populateDocumentChangeBuffer(txn, documentBuffer, documentMap, SnapshotVersion.min(), versionMap)
12588
+ return populateDocumentChangeBuffer(txn, documentBuffer, documentMap)
12400
12589
  .next(changedDocs => {
12401
12590
  documentBuffer.apply(txn);
12402
12591
  return changedDocs;
@@ -12877,15 +13066,14 @@ class MemoryRemoteDocumentCacheImpl {
12877
13066
  * All calls of `addEntry` are required to go through the RemoteDocumentChangeBuffer
12878
13067
  * returned by `newChangeBuffer()`.
12879
13068
  */
12880
- addEntry(transaction, doc, readTime) {
13069
+ addEntry(transaction, doc) {
12881
13070
  const key = doc.key;
12882
13071
  const entry = this.docs.get(key);
12883
13072
  const previousSize = entry ? entry.size : 0;
12884
13073
  const currentSize = this.sizer(doc);
12885
13074
  this.docs = this.docs.insert(key, {
12886
13075
  document: doc.mutableCopy(),
12887
- size: currentSize,
12888
- readTime
13076
+ size: currentSize
12889
13077
  });
12890
13078
  this.size += currentSize - previousSize;
12891
13079
  return this.indexManager.addToCollectionParentIndex(transaction, key.path.popLast());
@@ -12926,11 +13114,11 @@ class MemoryRemoteDocumentCacheImpl {
12926
13114
  const prefix = new DocumentKey(query.path.child(''));
12927
13115
  const iterator = this.docs.getIteratorFrom(prefix);
12928
13116
  while (iterator.hasNext()) {
12929
- const { key, value: { document, readTime } } = iterator.getNext();
13117
+ const { key, value: { document } } = iterator.getNext();
12930
13118
  if (!query.path.isPrefixOf(key.path)) {
12931
13119
  break;
12932
13120
  }
12933
- if (readTime.compareTo(sinceReadTime) <= 0) {
13121
+ if (document.readTime.compareTo(sinceReadTime) <= 0) {
12934
13122
  continue;
12935
13123
  }
12936
13124
  if (!queryMatches(query, document)) {
@@ -12974,8 +13162,8 @@ class MemoryRemoteDocumentChangeBuffer extends RemoteDocumentChangeBuffer {
12974
13162
  applyChanges(transaction) {
12975
13163
  const promises = [];
12976
13164
  this.changes.forEach((key, doc) => {
12977
- if (doc.document.isValidDocument()) {
12978
- promises.push(this.documentCache.addEntry(transaction, doc.document, this.getReadTime(key)));
13165
+ if (doc.isValidDocument()) {
13166
+ promises.push(this.documentCache.addEntry(transaction, doc));
12979
13167
  }
12980
13168
  else {
12981
13169
  this.documentCache.removeEntry(key);
@@ -13288,7 +13476,7 @@ class MemoryEagerDelegate {
13288
13476
  const key = DocumentKey.fromPath(path);
13289
13477
  return this.isReferenced(txn, key).next(isReferenced => {
13290
13478
  if (!isReferenced) {
13291
- changeBuffer.removeEntry(key);
13479
+ changeBuffer.removeEntry(key, SnapshotVersion.min());
13292
13480
  }
13293
13481
  });
13294
13482
  }).next(() => {
@@ -20345,6 +20533,9 @@ async function syncEngineRejectListen(syncEngine, targetId, err) {
20345
20533
  // store to purge a document. However, it would be tricky to keep all of
20346
20534
  // the local store's invariants with another method.
20347
20535
  let documentUpdates = new SortedMap(DocumentKey.comparator);
20536
+ // TODO(b/217189216): This limbo document should ideally have a read time,
20537
+ // so that it is picked up by any read-time based scans. The backend,
20538
+ // however, does not send a read time for target removals.
20348
20539
  documentUpdates = documentUpdates.insert(limboKey, MutableDocument.newNoDocument(limboKey, SnapshotVersion.min()));
20349
20540
  const resolvedLimboDocuments = documentKeySet().add(limboKey);
20350
20541
  const event = new RemoteEvent(SnapshotVersion.min(),
@@ -22289,72 +22480,6 @@ function createBundleReader(data, serializer) {
22289
22480
  return newBundleReader(toByteStreamReader(content), serializer);
22290
22481
  }
22291
22482
 
22292
- /**
22293
- * @license
22294
- * Copyright 2017 Google LLC
22295
- *
22296
- * Licensed under the Apache License, Version 2.0 (the "License");
22297
- * you may not use this file except in compliance with the License.
22298
- * You may obtain a copy of the License at
22299
- *
22300
- * http://www.apache.org/licenses/LICENSE-2.0
22301
- *
22302
- * Unless required by applicable law or agreed to in writing, software
22303
- * distributed under the License is distributed on an "AS IS" BASIS,
22304
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22305
- * See the License for the specific language governing permissions and
22306
- * limitations under the License.
22307
- */
22308
- class DatabaseInfo {
22309
- /**
22310
- * Constructs a DatabaseInfo using the provided host, databaseId and
22311
- * persistenceKey.
22312
- *
22313
- * @param databaseId - The database to use.
22314
- * @param appId - The Firebase App Id.
22315
- * @param persistenceKey - A unique identifier for this Firestore's local
22316
- * storage (used in conjunction with the databaseId).
22317
- * @param host - The Firestore backend host to connect to.
22318
- * @param ssl - Whether to use SSL when connecting.
22319
- * @param forceLongPolling - Whether to use the forceLongPolling option
22320
- * when using WebChannel as the network transport.
22321
- * @param autoDetectLongPolling - Whether to use the detectBufferingProxy
22322
- * option when using WebChannel as the network transport.
22323
- * @param useFetchStreams Whether to use the Fetch API instead of
22324
- * XMLHTTPRequest
22325
- */
22326
- constructor(databaseId, appId, persistenceKey, host, ssl, forceLongPolling, autoDetectLongPolling, useFetchStreams) {
22327
- this.databaseId = databaseId;
22328
- this.appId = appId;
22329
- this.persistenceKey = persistenceKey;
22330
- this.host = host;
22331
- this.ssl = ssl;
22332
- this.forceLongPolling = forceLongPolling;
22333
- this.autoDetectLongPolling = autoDetectLongPolling;
22334
- this.useFetchStreams = useFetchStreams;
22335
- }
22336
- }
22337
- /** The default database name for a project. */
22338
- const DEFAULT_DATABASE_NAME = '(default)';
22339
- /**
22340
- * Represents the database ID a Firestore client is associated with.
22341
- * @internal
22342
- */
22343
- class DatabaseId {
22344
- constructor(projectId, database) {
22345
- this.projectId = projectId;
22346
- this.database = database ? database : DEFAULT_DATABASE_NAME;
22347
- }
22348
- get isDefaultDatabase() {
22349
- return this.database === DEFAULT_DATABASE_NAME;
22350
- }
22351
- isEqual(other) {
22352
- return (other instanceof DatabaseId &&
22353
- other.projectId === this.projectId &&
22354
- other.database === this.database);
22355
- }
22356
- }
22357
-
22358
22483
  /**
22359
22484
  * @license
22360
22485
  * Copyright 2020 Google LLC
@@ -26268,17 +26393,6 @@ function writeBatch(firestore) {
26268
26393
  ensureFirestoreConfigured(firestore);
26269
26394
  return new WriteBatch(firestore, mutations => executeWrite(firestore, mutations));
26270
26395
  }
26271
- /** An index component consisting of field path and index type. */
26272
- class Segment {
26273
- constructor(
26274
- /** The field path of the component. */
26275
- fieldPath,
26276
- /** The fields sorting order. */
26277
- kind) {
26278
- this.fieldPath = fieldPath;
26279
- this.kind = kind;
26280
- }
26281
- }
26282
26396
 
26283
26397
  /**
26284
26398
  * @license
@@ -26302,27 +26416,29 @@ function setIndexConfiguration(firestore, jsonOrConfiguration) {
26302
26416
  const indexConfiguration = typeof jsonOrConfiguration === 'string'
26303
26417
  ? tryParseJson(jsonOrConfiguration)
26304
26418
  : jsonOrConfiguration;
26419
+ const parsedIndexes = [];
26305
26420
  // PORTING NOTE: We don't return an error if the user has not enabled
26306
26421
  // persistence since `enableIndexeddbPersistence()` can fail on the Web.
26307
26422
  if (Array.isArray(indexConfiguration.indexes)) {
26308
26423
  for (const index of indexConfiguration.indexes) {
26309
- tryGetString(index, 'collectionGroup');
26424
+ const collectionGroup = tryGetString(index, 'collectionGroup');
26310
26425
  const segments = [];
26311
26426
  if (Array.isArray(index.fields)) {
26312
26427
  for (const field of index.fields) {
26313
26428
  const fieldPathString = tryGetString(field, 'fieldPath');
26314
26429
  const fieldPath = fieldPathFromDotSeparatedString('setIndexConfiguration', fieldPathString);
26315
26430
  if (field.arrayConfig === 'CONTAINS') {
26316
- segments.push(new Segment(fieldPath, 2 /* CONTAINS */));
26431
+ segments.push(new IndexSegment(fieldPath, 2 /* CONTAINS */));
26317
26432
  }
26318
26433
  else if (field.order === 'ASCENDING') {
26319
- segments.push(new Segment(fieldPath, 0 /* ASCENDING */));
26434
+ segments.push(new IndexSegment(fieldPath, 0 /* ASCENDING */));
26320
26435
  }
26321
26436
  else if (field.order === 'DESCENDING') {
26322
- segments.push(new Segment(fieldPath, 1 /* DESCENDING */));
26437
+ segments.push(new IndexSegment(fieldPath, 1 /* DESCENDING */));
26323
26438
  }
26324
26439
  }
26325
26440
  }
26441
+ parsedIndexes.push(new FieldIndex(FieldIndex.UNKNOWN_ID, collectionGroup, segments, IndexState.empty()));
26326
26442
  }
26327
26443
  }
26328
26444
  // TODO(indexing): Configure indexes