@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
@@ -12,7 +12,7 @@ var grpcJs = require('@grpc/grpc-js');
12
12
  var protoLoader = require('@grpc/proto-loader');
13
13
 
14
14
  const name = "@firebase/firestore";
15
- const version$1 = "3.4.4-canary.222f264ff";
15
+ const version$1 = "3.4.4-canary.2dd99ae2d";
16
16
 
17
17
  /**
18
18
  * @license
@@ -65,7 +65,7 @@ User.GOOGLE_CREDENTIALS = new User('google-credentials-uid');
65
65
  User.FIRST_PARTY = new User('first-party-uid');
66
66
  User.MOCK_USER = new User('mock-user');
67
67
 
68
- const version = "9.6.5-canary.222f264ff";
68
+ const version = "9.6.5-canary.2dd99ae2d";
69
69
 
70
70
  /**
71
71
  * @license
@@ -3378,6 +3378,75 @@ function getLocalWriteTime(value) {
3378
3378
  return new Timestamp(localWriteTime.seconds, localWriteTime.nanos);
3379
3379
  }
3380
3380
 
3381
+ /**
3382
+ * @license
3383
+ * Copyright 2017 Google LLC
3384
+ *
3385
+ * Licensed under the Apache License, Version 2.0 (the "License");
3386
+ * you may not use this file except in compliance with the License.
3387
+ * You may obtain a copy of the License at
3388
+ *
3389
+ * http://www.apache.org/licenses/LICENSE-2.0
3390
+ *
3391
+ * Unless required by applicable law or agreed to in writing, software
3392
+ * distributed under the License is distributed on an "AS IS" BASIS,
3393
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3394
+ * See the License for the specific language governing permissions and
3395
+ * limitations under the License.
3396
+ */
3397
+ class DatabaseInfo {
3398
+ /**
3399
+ * Constructs a DatabaseInfo using the provided host, databaseId and
3400
+ * persistenceKey.
3401
+ *
3402
+ * @param databaseId - The database to use.
3403
+ * @param appId - The Firebase App Id.
3404
+ * @param persistenceKey - A unique identifier for this Firestore's local
3405
+ * storage (used in conjunction with the databaseId).
3406
+ * @param host - The Firestore backend host to connect to.
3407
+ * @param ssl - Whether to use SSL when connecting.
3408
+ * @param forceLongPolling - Whether to use the forceLongPolling option
3409
+ * when using WebChannel as the network transport.
3410
+ * @param autoDetectLongPolling - Whether to use the detectBufferingProxy
3411
+ * option when using WebChannel as the network transport.
3412
+ * @param useFetchStreams Whether to use the Fetch API instead of
3413
+ * XMLHTTPRequest
3414
+ */
3415
+ constructor(databaseId, appId, persistenceKey, host, ssl, forceLongPolling, autoDetectLongPolling, useFetchStreams) {
3416
+ this.databaseId = databaseId;
3417
+ this.appId = appId;
3418
+ this.persistenceKey = persistenceKey;
3419
+ this.host = host;
3420
+ this.ssl = ssl;
3421
+ this.forceLongPolling = forceLongPolling;
3422
+ this.autoDetectLongPolling = autoDetectLongPolling;
3423
+ this.useFetchStreams = useFetchStreams;
3424
+ }
3425
+ }
3426
+ /** The default database name for a project. */
3427
+ const DEFAULT_DATABASE_NAME = '(default)';
3428
+ /**
3429
+ * Represents the database ID a Firestore client is associated with.
3430
+ * @internal
3431
+ */
3432
+ class DatabaseId {
3433
+ constructor(projectId, database) {
3434
+ this.projectId = projectId;
3435
+ this.database = database ? database : DEFAULT_DATABASE_NAME;
3436
+ }
3437
+ static empty() {
3438
+ return new DatabaseId('', '');
3439
+ }
3440
+ get isDefaultDatabase() {
3441
+ return this.database === DEFAULT_DATABASE_NAME;
3442
+ }
3443
+ isEqual(other) {
3444
+ return (other instanceof DatabaseId &&
3445
+ other.projectId === this.projectId &&
3446
+ other.database === this.database);
3447
+ }
3448
+ }
3449
+
3381
3450
  /**
3382
3451
  * @license
3383
3452
  * Copyright 2017 Google LLC
@@ -3449,6 +3518,9 @@ class DocumentKey {
3449
3518
  static fromName(name) {
3450
3519
  return new DocumentKey(ResourcePath.fromString(name).popFirst(5));
3451
3520
  }
3521
+ static empty() {
3522
+ return new DocumentKey(ResourcePath.emptyPath());
3523
+ }
3452
3524
  /** Returns true if the document is in the specified collectionId. */
3453
3525
  hasCollectionId(collectionId) {
3454
3526
  return (this.path.length >= 2 &&
@@ -4097,10 +4169,11 @@ function extractFieldMask(value) {
4097
4169
  * from all views.
4098
4170
  */
4099
4171
  class MutableDocument {
4100
- constructor(key, documentType, version, data, documentState) {
4172
+ constructor(key, documentType, version, readTime, data, documentState) {
4101
4173
  this.key = key;
4102
4174
  this.documentType = documentType;
4103
4175
  this.version = version;
4176
+ this.readTime = readTime;
4104
4177
  this.data = data;
4105
4178
  this.documentState = documentState;
4106
4179
  }
@@ -4109,18 +4182,18 @@ class MutableDocument {
4109
4182
  * base document for mutations.
4110
4183
  */
4111
4184
  static newInvalidDocument(documentKey) {
4112
- return new MutableDocument(documentKey, 0 /* INVALID */, SnapshotVersion.min(), ObjectValue.empty(), 0 /* SYNCED */);
4185
+ return new MutableDocument(documentKey, 0 /* INVALID */, SnapshotVersion.min(), SnapshotVersion.min(), ObjectValue.empty(), 0 /* SYNCED */);
4113
4186
  }
4114
4187
  /**
4115
4188
  * Creates a new document that is known to exist with the given data at the
4116
4189
  * given version.
4117
4190
  */
4118
4191
  static newFoundDocument(documentKey, version, value) {
4119
- return new MutableDocument(documentKey, 1 /* FOUND_DOCUMENT */, version, value, 0 /* SYNCED */);
4192
+ return new MutableDocument(documentKey, 1 /* FOUND_DOCUMENT */, version, SnapshotVersion.min(), value, 0 /* SYNCED */);
4120
4193
  }
4121
4194
  /** Creates a new document that is known to not exist at the given version. */
4122
4195
  static newNoDocument(documentKey, version) {
4123
- return new MutableDocument(documentKey, 2 /* NO_DOCUMENT */, version, ObjectValue.empty(), 0 /* SYNCED */);
4196
+ return new MutableDocument(documentKey, 2 /* NO_DOCUMENT */, version, SnapshotVersion.min(), ObjectValue.empty(), 0 /* SYNCED */);
4124
4197
  }
4125
4198
  /**
4126
4199
  * Creates a new document that is known to exist at the given version but
@@ -4128,7 +4201,7 @@ class MutableDocument {
4128
4201
  * base document).
4129
4202
  */
4130
4203
  static newUnknownDocument(documentKey, version) {
4131
- return new MutableDocument(documentKey, 3 /* UNKNOWN_DOCUMENT */, version, ObjectValue.empty(), 2 /* HAS_COMMITTED_MUTATIONS */);
4204
+ return new MutableDocument(documentKey, 3 /* UNKNOWN_DOCUMENT */, version, SnapshotVersion.min(), ObjectValue.empty(), 2 /* HAS_COMMITTED_MUTATIONS */);
4132
4205
  }
4133
4206
  /**
4134
4207
  * Changes the document type to indicate that it exists and that its version
@@ -4172,6 +4245,10 @@ class MutableDocument {
4172
4245
  this.documentState = 1 /* HAS_LOCAL_MUTATIONS */;
4173
4246
  return this;
4174
4247
  }
4248
+ setReadTime(readTime) {
4249
+ this.readTime = readTime;
4250
+ return this;
4251
+ }
4175
4252
  get hasLocalMutations() {
4176
4253
  return this.documentState === 1 /* HAS_LOCAL_MUTATIONS */;
4177
4254
  }
@@ -4202,7 +4279,7 @@ class MutableDocument {
4202
4279
  this.data.isEqual(other.data));
4203
4280
  }
4204
4281
  mutableCopy() {
4205
- return new MutableDocument(this.key, this.documentType, this.version, this.data.clone(), this.documentState);
4282
+ return new MutableDocument(this.key, this.documentType, this.version, this.readTime, this.data.clone(), this.documentState);
4206
4283
  }
4207
4284
  toString() {
4208
4285
  return (`Document(${this.key}, ${this.version}, ${JSON.stringify(this.data.value)}, ` +
@@ -4225,6 +4302,125 @@ function compareDocumentsByField(field, d1, d2) {
4225
4302
  }
4226
4303
  }
4227
4304
 
4305
+ /**
4306
+ * @license
4307
+ * Copyright 2021 Google LLC
4308
+ *
4309
+ * Licensed under the Apache License, Version 2.0 (the "License");
4310
+ * you may not use this file except in compliance with the License.
4311
+ * You may obtain a copy of the License at
4312
+ *
4313
+ * http://www.apache.org/licenses/LICENSE-2.0
4314
+ *
4315
+ * Unless required by applicable law or agreed to in writing, software
4316
+ * distributed under the License is distributed on an "AS IS" BASIS,
4317
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4318
+ * See the License for the specific language governing permissions and
4319
+ * limitations under the License.
4320
+ */
4321
+ /**
4322
+ * The initial mutation batch id for each index. Gets updated during index
4323
+ * backfill.
4324
+ */
4325
+ const INITIAL_LARGEST_BATCH_ID = -1;
4326
+ /**
4327
+ * The initial sequence number for each index. Gets updated during index
4328
+ * backfill.
4329
+ */
4330
+ const INITIAL_SEQUENCE_NUMBER = 0;
4331
+ /**
4332
+ * An index definition for field indexes in Firestore.
4333
+ *
4334
+ * Every index is associated with a collection. The definition contains a list
4335
+ * of fields and their index kind (which can be `ASCENDING`, `DESCENDING` or
4336
+ * `CONTAINS` for ArrayContains/ArrayContainsAny queries).
4337
+ *
4338
+ * Unlike the backend, the SDK does not differentiate between collection or
4339
+ * collection group-scoped indices. Every index can be used for both single
4340
+ * collection and collection group queries.
4341
+ */
4342
+ class FieldIndex {
4343
+ constructor(
4344
+ /**
4345
+ * The index ID. Returns -1 if the index ID is not available (e.g. the index
4346
+ * has not yet been persisted).
4347
+ */
4348
+ indexId,
4349
+ /** The collection ID this index applies to. */
4350
+ collectionGroup,
4351
+ /** The field segments for this index. */
4352
+ segments,
4353
+ /** Shows how up-to-date the index is for the current user. */
4354
+ indexState) {
4355
+ this.indexId = indexId;
4356
+ this.collectionGroup = collectionGroup;
4357
+ this.segments = segments;
4358
+ this.indexState = indexState;
4359
+ }
4360
+ }
4361
+ /** An ID for an index that has not yet been added to persistence. */
4362
+ FieldIndex.UNKNOWN_ID = -1;
4363
+ /** An index component consisting of field path and index type. */
4364
+ class IndexSegment {
4365
+ constructor(
4366
+ /** The field path of the component. */
4367
+ fieldPath,
4368
+ /** The fields sorting order. */
4369
+ kind) {
4370
+ this.fieldPath = fieldPath;
4371
+ this.kind = kind;
4372
+ }
4373
+ }
4374
+ /**
4375
+ * Stores the "high water mark" that indicates how updated the Index is for the
4376
+ * current user.
4377
+ */
4378
+ class IndexState {
4379
+ constructor(
4380
+ /**
4381
+ * Indicates when the index was last updated (relative to other indexes).
4382
+ */
4383
+ sequenceNumber,
4384
+ /** The the latest indexed read time, document and batch id. */
4385
+ offset) {
4386
+ this.sequenceNumber = sequenceNumber;
4387
+ this.offset = offset;
4388
+ }
4389
+ /** The state of an index that has not yet been backfilled. */
4390
+ static empty() {
4391
+ return new IndexState(INITIAL_SEQUENCE_NUMBER, IndexOffset.min());
4392
+ }
4393
+ }
4394
+ /**
4395
+ * Stores the latest read time, document and batch ID that were processed for an
4396
+ * index.
4397
+ */
4398
+ class IndexOffset {
4399
+ constructor(
4400
+ /**
4401
+ * The latest read time version that has been indexed by Firestore for this
4402
+ * field index.
4403
+ */
4404
+ readTime,
4405
+ /**
4406
+ * The key of the last document that was indexed for this query. Use
4407
+ * `DocumentKey.empty()` if no document has been indexed.
4408
+ */
4409
+ documentKey,
4410
+ /*
4411
+ * The largest mutation batch id that's been processed by Firestore.
4412
+ */
4413
+ largestBatchId) {
4414
+ this.readTime = readTime;
4415
+ this.documentKey = documentKey;
4416
+ this.largestBatchId = largestBatchId;
4417
+ }
4418
+ /** The state of an index that has not yet been backfilled. */
4419
+ static min() {
4420
+ return new IndexOffset(SnapshotVersion.min(), DocumentKey.empty(), INITIAL_LARGEST_BATCH_ID);
4421
+ }
4422
+ }
4423
+
4228
4424
  /**
4229
4425
  * @license
4230
4426
  * Copyright 2019 Google LLC
@@ -4349,7 +4545,7 @@ function targetEquals(left, right) {
4349
4545
  }
4350
4546
  return boundEquals(left.endAt, right.endAt);
4351
4547
  }
4352
- function isDocumentTarget(target) {
4548
+ function targetIsDocumentTarget(target) {
4353
4549
  return (DocumentKey.isDocumentKey(target.path) &&
4354
4550
  target.collectionGroup === null &&
4355
4551
  target.filters.length === 0);
@@ -4537,6 +4733,7 @@ class ArrayContainsAnyFilter extends FieldFilter {
4537
4733
  return other.arrayValue.values.some(val => arrayValueContains(this.value.arrayValue, val));
4538
4734
  }
4539
4735
  }
4736
+ // TODO(indexing): Change Bound.before to "inclusive"
4540
4737
  /**
4541
4738
  * Represents a bound of a query.
4542
4739
  *
@@ -6994,7 +7191,7 @@ class WatchChangeAggregator {
6994
7191
  const targetData = this.targetDataForActiveTarget(targetId);
6995
7192
  if (targetData) {
6996
7193
  const target = targetData.target;
6997
- if (isDocumentTarget(target)) {
7194
+ if (targetIsDocumentTarget(target)) {
6998
7195
  if (expectedCount === 0) {
6999
7196
  // The existence filter told us the document does not exist. We deduce
7000
7197
  // that this document does not exist and apply a deleted document to
@@ -7029,7 +7226,7 @@ class WatchChangeAggregator {
7029
7226
  this.targetStates.forEach((targetState, targetId) => {
7030
7227
  const targetData = this.targetDataForActiveTarget(targetId);
7031
7228
  if (targetData) {
7032
- if (targetState.current && isDocumentTarget(targetData.target)) {
7229
+ if (targetState.current && targetIsDocumentTarget(targetData.target)) {
7033
7230
  // Document queries for document that don't exist can produce an empty
7034
7231
  // result set. To update our local cache, we synthesize a document
7035
7232
  // delete if we have not previously received the document. This
@@ -7072,6 +7269,7 @@ class WatchChangeAggregator {
7072
7269
  resolvedLimboDocuments = resolvedLimboDocuments.add(key);
7073
7270
  }
7074
7271
  });
7272
+ this.pendingDocumentUpdates.forEach((_, doc) => doc.setReadTime(snapshotVersion));
7075
7273
  const remoteEvent = new RemoteEvent(snapshotVersion, targetChanges, this.pendingTargetResets, this.pendingDocumentUpdates, resolvedLimboDocuments);
7076
7274
  this.pendingDocumentUpdates = mutableDocumentMap();
7077
7275
  this.pendingDocumentTargetMapping = documentTargetMap();
@@ -7864,7 +8062,7 @@ function toLabel(serializer, purpose) {
7864
8062
  function toTarget(serializer, targetData) {
7865
8063
  let result;
7866
8064
  const target = targetData.target;
7867
- if (isDocumentTarget(target)) {
8065
+ if (targetIsDocumentTarget(target)) {
7868
8066
  result = { documents: toDocumentsTarget(serializer, target) };
7869
8067
  }
7870
8068
  else {
@@ -8192,29 +8390,34 @@ class LocalSerializer {
8192
8390
  }
8193
8391
  /** Decodes a remote document from storage locally to a Document. */
8194
8392
  function fromDbRemoteDocument(localSerializer, remoteDoc) {
8393
+ let doc;
8195
8394
  if (remoteDoc.document) {
8196
- return fromDocument(localSerializer.remoteSerializer, remoteDoc.document, !!remoteDoc.hasCommittedMutations);
8395
+ doc = fromDocument(localSerializer.remoteSerializer, remoteDoc.document, !!remoteDoc.hasCommittedMutations);
8197
8396
  }
8198
8397
  else if (remoteDoc.noDocument) {
8199
8398
  const key = DocumentKey.fromSegments(remoteDoc.noDocument.path);
8200
8399
  const version = fromDbTimestamp(remoteDoc.noDocument.readTime);
8201
- const document = MutableDocument.newNoDocument(key, version);
8202
- return remoteDoc.hasCommittedMutations
8203
- ? document.setHasCommittedMutations()
8204
- : document;
8400
+ doc = MutableDocument.newNoDocument(key, version);
8401
+ if (remoteDoc.hasCommittedMutations) {
8402
+ doc.setHasCommittedMutations();
8403
+ }
8205
8404
  }
8206
8405
  else if (remoteDoc.unknownDocument) {
8207
8406
  const key = DocumentKey.fromSegments(remoteDoc.unknownDocument.path);
8208
8407
  const version = fromDbTimestamp(remoteDoc.unknownDocument.version);
8209
- return MutableDocument.newUnknownDocument(key, version);
8408
+ doc = MutableDocument.newUnknownDocument(key, version);
8210
8409
  }
8211
8410
  else {
8212
8411
  return fail();
8213
8412
  }
8413
+ if (remoteDoc.readTime) {
8414
+ doc.setReadTime(fromDbTimestampKey(remoteDoc.readTime));
8415
+ }
8416
+ return doc;
8214
8417
  }
8215
8418
  /** Encodes a document for storage locally. */
8216
- function toDbRemoteDocument(localSerializer, document, readTime) {
8217
- const dbReadTime = toDbTimestampKey(readTime);
8419
+ function toDbRemoteDocument(localSerializer, document) {
8420
+ const dbReadTime = toDbTimestampKey(document.readTime);
8218
8421
  const parentPath = document.key.path.popLast().toArray();
8219
8422
  if (document.isFoundDocument()) {
8220
8423
  const doc = toDocument(localSerializer.remoteSerializer, document);
@@ -8225,10 +8428,10 @@ function toDbRemoteDocument(localSerializer, document, readTime) {
8225
8428
  }
8226
8429
  else if (document.isNoDocument()) {
8227
8430
  const path = document.key.path.toArray();
8228
- const readTime = toDbTimestamp(document.version);
8431
+ const version = toDbTimestamp(document.version);
8229
8432
  const hasCommittedMutations = document.hasCommittedMutations;
8230
8433
  return new DbRemoteDocument(
8231
- /* unknownDocument= */ null, new DbNoDocument(path, readTime),
8434
+ /* unknownDocument= */ null, new DbNoDocument(path, version),
8232
8435
  /* document= */ null, hasCommittedMutations, dbReadTime, parentPath);
8233
8436
  }
8234
8437
  else if (document.isUnknownDocument()) {
@@ -8309,7 +8512,7 @@ function toDbTarget(localSerializer, targetData) {
8309
8512
  const dbTimestamp = toDbTimestamp(targetData.snapshotVersion);
8310
8513
  const dbLastLimboFreeTimestamp = toDbTimestamp(targetData.lastLimboFreeSnapshotVersion);
8311
8514
  let queryProto;
8312
- if (isDocumentTarget(targetData.target)) {
8515
+ if (targetIsDocumentTarget(targetData.target)) {
8313
8516
  queryProto = toDocumentsTarget(localSerializer.remoteSerializer, targetData.target);
8314
8517
  }
8315
8518
  else {
@@ -9757,7 +9960,7 @@ class IndexedDbLruDelegateImpl {
9757
9960
  // Our size accounting requires us to read all documents before
9758
9961
  // removing them.
9759
9962
  return changeBuffer.getEntry(txn, docKey).next(() => {
9760
- changeBuffer.removeEntry(docKey);
9963
+ changeBuffer.removeEntry(docKey, SnapshotVersion.min());
9761
9964
  return documentTargetStore(txn).delete(sentinelKey$1(docKey));
9762
9965
  });
9763
9966
  }
@@ -9970,27 +10173,19 @@ class ObjectMap {
9970
10173
  */
9971
10174
  class RemoteDocumentChangeBuffer {
9972
10175
  constructor() {
9973
- // A mapping of document key to the new cache entry that should be written (or null if any
9974
- // existing cache entry should be removed).
10176
+ // A mapping of document key to the new cache entry that should be written.
9975
10177
  this.changes = new ObjectMap(key => key.toString(), (l, r) => l.isEqual(r));
9976
10178
  this.changesApplied = false;
9977
10179
  }
9978
- getReadTime(key) {
9979
- const change = this.changes.get(key);
9980
- if (change) {
9981
- return change.readTime;
9982
- }
9983
- return SnapshotVersion.min();
9984
- }
9985
10180
  /**
9986
10181
  * Buffers a `RemoteDocumentCache.addEntry()` call.
9987
10182
  *
9988
10183
  * You can only modify documents that have already been retrieved via
9989
10184
  * `getEntry()/getEntries()` (enforced via IndexedDbs `apply()`).
9990
10185
  */
9991
- addEntry(document, readTime) {
10186
+ addEntry(document) {
9992
10187
  this.assertNotApplied();
9993
- this.changes.set(document.key, { document, readTime });
10188
+ this.changes.set(document.key, document);
9994
10189
  }
9995
10190
  /**
9996
10191
  * Buffers a `RemoteDocumentCache.removeEntry()` call.
@@ -9998,12 +10193,9 @@ class RemoteDocumentChangeBuffer {
9998
10193
  * You can only remove documents that have already been retrieved via
9999
10194
  * `getEntry()/getEntries()` (enforced via IndexedDbs `apply()`).
10000
10195
  */
10001
- removeEntry(key, readTime = null) {
10196
+ removeEntry(key, readTime) {
10002
10197
  this.assertNotApplied();
10003
- this.changes.set(key, {
10004
- document: MutableDocument.newInvalidDocument(key),
10005
- readTime
10006
- });
10198
+ this.changes.set(key, MutableDocument.newInvalidDocument(key).setReadTime(readTime));
10007
10199
  }
10008
10200
  /**
10009
10201
  * Looks up an entry in the cache. The buffered changes will first be checked,
@@ -10020,7 +10212,7 @@ class RemoteDocumentChangeBuffer {
10020
10212
  this.assertNotApplied();
10021
10213
  const bufferedEntry = this.changes.get(documentKey);
10022
10214
  if (bufferedEntry !== undefined) {
10023
- return PersistencePromise.resolve(bufferedEntry.document);
10215
+ return PersistencePromise.resolve(bufferedEntry);
10024
10216
  }
10025
10217
  else {
10026
10218
  return this.getFromCache(transaction, documentKey);
@@ -10231,7 +10423,7 @@ class IndexedDbRemoteDocumentCacheImpl {
10231
10423
  if (key.length !== immediateChildrenPathLength) {
10232
10424
  return;
10233
10425
  }
10234
- const document = fromDbRemoteDocument(this.serializer, dbRemoteDoc);
10426
+ const document = this.maybeDecodeDocument(DocumentKey.fromSegments(key), dbRemoteDoc);
10235
10427
  if (!query.path.isPrefixOf(document.key.path)) {
10236
10428
  control.done();
10237
10429
  }
@@ -10259,8 +10451,8 @@ class IndexedDbRemoteDocumentCacheImpl {
10259
10451
  return documentGlobalStore(txn).put(DbRemoteDocumentGlobal.key, metadata);
10260
10452
  }
10261
10453
  /**
10262
- * Decodes `remoteDoc` and returns the document (or null, if the document
10263
- * corresponds to the format used for sentinel deletes).
10454
+ * Decodes `dbRemoteDoc` and returns the document (or an invalid document if
10455
+ * the document corresponds to the format used for sentinel deletes).
10264
10456
  */
10265
10457
  maybeDecodeDocument(documentKey, dbRemoteDoc) {
10266
10458
  if (dbRemoteDoc) {
@@ -10354,8 +10546,8 @@ class IndexedDbRemoteDocumentChangeBuffer extends RemoteDocumentChangeBuffer {
10354
10546
  let collectionParents = new SortedSet((l, r) => primitiveComparator(l.canonicalString(), r.canonicalString()));
10355
10547
  this.changes.forEach((key, documentChange) => {
10356
10548
  const previousSize = this.documentSizes.get(key);
10357
- if (documentChange.document.isValidDocument()) {
10358
- const doc = toDbRemoteDocument(this.documentCache.serializer, documentChange.document, this.getReadTime(key));
10549
+ if (documentChange.isValidDocument()) {
10550
+ const doc = toDbRemoteDocument(this.documentCache.serializer, documentChange);
10359
10551
  collectionParents = collectionParents.add(key.path.popLast());
10360
10552
  const size = dbDocumentSize(doc);
10361
10553
  sizeDelta += size - previousSize;
@@ -10368,7 +10560,7 @@ class IndexedDbRemoteDocumentChangeBuffer extends RemoteDocumentChangeBuffer {
10368
10560
  // RemoteDocumentCache. This entry is represented by a NoDocument
10369
10561
  // with a version of 0 and ignored by `maybeDecodeDocument()` but
10370
10562
  // preserved in `getNewDocumentChanges()`.
10371
- const deletedDoc = toDbRemoteDocument(this.documentCache.serializer, MutableDocument.newNoDocument(key, SnapshotVersion.min()), this.getReadTime(key));
10563
+ const deletedDoc = toDbRemoteDocument(this.documentCache.serializer, documentChange.convertToNoDocument(SnapshotVersion.min()));
10372
10564
  promises.push(this.documentCache.addEntry(transaction, key, deletedDoc));
10373
10565
  }
10374
10566
  else {
@@ -11955,14 +12147,14 @@ function localStoreApplyRemoteEventToLocalCache(localStore, remoteEvent) {
11955
12147
  }
11956
12148
  });
11957
12149
  let changedDocs = mutableDocumentMap();
11958
- remoteEvent.documentUpdates.forEach((key, doc) => {
12150
+ remoteEvent.documentUpdates.forEach(key => {
11959
12151
  if (remoteEvent.resolvedLimboDocuments.has(key)) {
11960
12152
  promises.push(localStoreImpl.persistence.referenceDelegate.updateLimboDocument(txn, key));
11961
12153
  }
11962
12154
  });
11963
12155
  // Each loop iteration only affects its "own" doc, so it's safe to get all the remote
11964
12156
  // documents in advance in a single call.
11965
- promises.push(populateDocumentChangeBuffer(txn, documentBuffer, remoteEvent.documentUpdates, remoteVersion, undefined).next(result => {
12157
+ promises.push(populateDocumentChangeBuffer(txn, documentBuffer, remoteEvent.documentUpdates).next(result => {
11966
12158
  changedDocs = result;
11967
12159
  }));
11968
12160
  // HACK: The only reason we allow a null snapshot version is so that we
@@ -12003,17 +12195,13 @@ function localStoreApplyRemoteEventToLocalCache(localStore, remoteEvent) {
12003
12195
  * Note: this function will use `documentVersions` if it is defined;
12004
12196
  * when it is not defined, resorts to `globalVersion`.
12005
12197
  */
12006
- function populateDocumentChangeBuffer(txn, documentBuffer, documents, globalVersion,
12007
- // TODO(wuandy): We could add `readTime` to MaybeDocument instead to remove
12008
- // this parameter.
12009
- documentVersions) {
12198
+ function populateDocumentChangeBuffer(txn, documentBuffer, documents) {
12010
12199
  let updatedKeys = documentKeySet();
12011
12200
  documents.forEach(k => (updatedKeys = updatedKeys.add(k)));
12012
12201
  return documentBuffer.getEntries(txn, updatedKeys).next(existingDocs => {
12013
12202
  let changedDocs = mutableDocumentMap();
12014
12203
  documents.forEach((key, doc) => {
12015
12204
  const existingDoc = existingDocs.get(key);
12016
- const docReadTime = (documentVersions === null || documentVersions === void 0 ? void 0 : documentVersions.get(key)) || globalVersion;
12017
12205
  // Note: The order of the steps below is important, since we want
12018
12206
  // to ensure that rejected limbo resolutions (which fabricate
12019
12207
  // NoDocuments with SnapshotVersion.min()) never add documents to
@@ -12022,14 +12210,14 @@ documentVersions) {
12022
12210
  // NoDocuments with SnapshotVersion.min() are used in manufactured
12023
12211
  // events. We remove these documents from cache since we lost
12024
12212
  // access.
12025
- documentBuffer.removeEntry(key, docReadTime);
12213
+ documentBuffer.removeEntry(key, doc.readTime);
12026
12214
  changedDocs = changedDocs.insert(key, doc);
12027
12215
  }
12028
12216
  else if (!existingDoc.isValidDocument() ||
12029
12217
  doc.version.compareTo(existingDoc.version) > 0 ||
12030
12218
  (doc.version.compareTo(existingDoc.version) === 0 &&
12031
12219
  existingDoc.hasPendingWrites)) {
12032
- documentBuffer.addEntry(doc, docReadTime);
12220
+ documentBuffer.addEntry(doc);
12033
12221
  changedDocs = changedDocs.insert(key, doc);
12034
12222
  }
12035
12223
  else {
@@ -12283,7 +12471,8 @@ function applyWriteToRemoteDocuments(localStoreImpl, txn, batchResult, documentB
12283
12471
  // We use the commitVersion as the readTime rather than the
12284
12472
  // document's updateTime since the updateTime is not advanced
12285
12473
  // for updates that do not modify the underlying document.
12286
- documentBuffer.addEntry(doc, batchResult.commitVersion);
12474
+ doc.setReadTime(batchResult.commitVersion);
12475
+ documentBuffer.addEntry(doc);
12287
12476
  }
12288
12477
  }
12289
12478
  });
@@ -12384,14 +12573,14 @@ async function localStoreApplyBundledDocuments(localStore, bundleConverter, docu
12384
12573
  const localStoreImpl = debugCast(localStore);
12385
12574
  let documentKeys = documentKeySet();
12386
12575
  let documentMap = mutableDocumentMap();
12387
- let versionMap = documentVersionMap();
12388
12576
  for (const bundleDoc of documents) {
12389
12577
  const documentKey = bundleConverter.toDocumentKey(bundleDoc.metadata.name);
12390
12578
  if (bundleDoc.document) {
12391
12579
  documentKeys = documentKeys.add(documentKey);
12392
12580
  }
12393
- documentMap = documentMap.insert(documentKey, bundleConverter.toMutableDocument(bundleDoc));
12394
- versionMap = versionMap.insert(documentKey, bundleConverter.toSnapshotVersion(bundleDoc.metadata.readTime));
12581
+ const doc = bundleConverter.toMutableDocument(bundleDoc);
12582
+ doc.setReadTime(bundleConverter.toSnapshotVersion(bundleDoc.metadata.readTime));
12583
+ documentMap = documentMap.insert(documentKey, doc);
12395
12584
  }
12396
12585
  const documentBuffer = localStoreImpl.remoteDocuments.newChangeBuffer({
12397
12586
  trackRemovals: true // Make sure document removals show up in `getNewDocumentChanges()`
@@ -12400,7 +12589,7 @@ async function localStoreApplyBundledDocuments(localStore, bundleConverter, docu
12400
12589
  // they will not get garbage collected right away.
12401
12590
  const umbrellaTargetData = await localStoreAllocateTarget(localStoreImpl, umbrellaTarget(bundleName));
12402
12591
  return localStoreImpl.persistence.runTransaction('Apply bundle documents', 'readwrite', txn => {
12403
- return populateDocumentChangeBuffer(txn, documentBuffer, documentMap, SnapshotVersion.min(), versionMap)
12592
+ return populateDocumentChangeBuffer(txn, documentBuffer, documentMap)
12404
12593
  .next(changedDocs => {
12405
12594
  documentBuffer.apply(txn);
12406
12595
  return changedDocs;
@@ -12881,15 +13070,14 @@ class MemoryRemoteDocumentCacheImpl {
12881
13070
  * All calls of `addEntry` are required to go through the RemoteDocumentChangeBuffer
12882
13071
  * returned by `newChangeBuffer()`.
12883
13072
  */
12884
- addEntry(transaction, doc, readTime) {
13073
+ addEntry(transaction, doc) {
12885
13074
  const key = doc.key;
12886
13075
  const entry = this.docs.get(key);
12887
13076
  const previousSize = entry ? entry.size : 0;
12888
13077
  const currentSize = this.sizer(doc);
12889
13078
  this.docs = this.docs.insert(key, {
12890
13079
  document: doc.mutableCopy(),
12891
- size: currentSize,
12892
- readTime
13080
+ size: currentSize
12893
13081
  });
12894
13082
  this.size += currentSize - previousSize;
12895
13083
  return this.indexManager.addToCollectionParentIndex(transaction, key.path.popLast());
@@ -12930,11 +13118,11 @@ class MemoryRemoteDocumentCacheImpl {
12930
13118
  const prefix = new DocumentKey(query.path.child(''));
12931
13119
  const iterator = this.docs.getIteratorFrom(prefix);
12932
13120
  while (iterator.hasNext()) {
12933
- const { key, value: { document, readTime } } = iterator.getNext();
13121
+ const { key, value: { document } } = iterator.getNext();
12934
13122
  if (!query.path.isPrefixOf(key.path)) {
12935
13123
  break;
12936
13124
  }
12937
- if (readTime.compareTo(sinceReadTime) <= 0) {
13125
+ if (document.readTime.compareTo(sinceReadTime) <= 0) {
12938
13126
  continue;
12939
13127
  }
12940
13128
  if (!queryMatches(query, document)) {
@@ -12978,8 +13166,8 @@ class MemoryRemoteDocumentChangeBuffer extends RemoteDocumentChangeBuffer {
12978
13166
  applyChanges(transaction) {
12979
13167
  const promises = [];
12980
13168
  this.changes.forEach((key, doc) => {
12981
- if (doc.document.isValidDocument()) {
12982
- promises.push(this.documentCache.addEntry(transaction, doc.document, this.getReadTime(key)));
13169
+ if (doc.isValidDocument()) {
13170
+ promises.push(this.documentCache.addEntry(transaction, doc));
12983
13171
  }
12984
13172
  else {
12985
13173
  this.documentCache.removeEntry(key);
@@ -13292,7 +13480,7 @@ class MemoryEagerDelegate {
13292
13480
  const key = DocumentKey.fromPath(path);
13293
13481
  return this.isReferenced(txn, key).next(isReferenced => {
13294
13482
  if (!isReferenced) {
13295
- changeBuffer.removeEntry(key);
13483
+ changeBuffer.removeEntry(key, SnapshotVersion.min());
13296
13484
  }
13297
13485
  });
13298
13486
  }).next(() => {
@@ -20349,6 +20537,9 @@ async function syncEngineRejectListen(syncEngine, targetId, err) {
20349
20537
  // store to purge a document. However, it would be tricky to keep all of
20350
20538
  // the local store's invariants with another method.
20351
20539
  let documentUpdates = new SortedMap(DocumentKey.comparator);
20540
+ // TODO(b/217189216): This limbo document should ideally have a read time,
20541
+ // so that it is picked up by any read-time based scans. The backend,
20542
+ // however, does not send a read time for target removals.
20352
20543
  documentUpdates = documentUpdates.insert(limboKey, MutableDocument.newNoDocument(limboKey, SnapshotVersion.min()));
20353
20544
  const resolvedLimboDocuments = documentKeySet().add(limboKey);
20354
20545
  const event = new RemoteEvent(SnapshotVersion.min(),
@@ -22293,72 +22484,6 @@ function createBundleReader(data, serializer) {
22293
22484
  return newBundleReader(toByteStreamReader(content), serializer);
22294
22485
  }
22295
22486
 
22296
- /**
22297
- * @license
22298
- * Copyright 2017 Google LLC
22299
- *
22300
- * Licensed under the Apache License, Version 2.0 (the "License");
22301
- * you may not use this file except in compliance with the License.
22302
- * You may obtain a copy of the License at
22303
- *
22304
- * http://www.apache.org/licenses/LICENSE-2.0
22305
- *
22306
- * Unless required by applicable law or agreed to in writing, software
22307
- * distributed under the License is distributed on an "AS IS" BASIS,
22308
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22309
- * See the License for the specific language governing permissions and
22310
- * limitations under the License.
22311
- */
22312
- class DatabaseInfo {
22313
- /**
22314
- * Constructs a DatabaseInfo using the provided host, databaseId and
22315
- * persistenceKey.
22316
- *
22317
- * @param databaseId - The database to use.
22318
- * @param appId - The Firebase App Id.
22319
- * @param persistenceKey - A unique identifier for this Firestore's local
22320
- * storage (used in conjunction with the databaseId).
22321
- * @param host - The Firestore backend host to connect to.
22322
- * @param ssl - Whether to use SSL when connecting.
22323
- * @param forceLongPolling - Whether to use the forceLongPolling option
22324
- * when using WebChannel as the network transport.
22325
- * @param autoDetectLongPolling - Whether to use the detectBufferingProxy
22326
- * option when using WebChannel as the network transport.
22327
- * @param useFetchStreams Whether to use the Fetch API instead of
22328
- * XMLHTTPRequest
22329
- */
22330
- constructor(databaseId, appId, persistenceKey, host, ssl, forceLongPolling, autoDetectLongPolling, useFetchStreams) {
22331
- this.databaseId = databaseId;
22332
- this.appId = appId;
22333
- this.persistenceKey = persistenceKey;
22334
- this.host = host;
22335
- this.ssl = ssl;
22336
- this.forceLongPolling = forceLongPolling;
22337
- this.autoDetectLongPolling = autoDetectLongPolling;
22338
- this.useFetchStreams = useFetchStreams;
22339
- }
22340
- }
22341
- /** The default database name for a project. */
22342
- const DEFAULT_DATABASE_NAME = '(default)';
22343
- /**
22344
- * Represents the database ID a Firestore client is associated with.
22345
- * @internal
22346
- */
22347
- class DatabaseId {
22348
- constructor(projectId, database) {
22349
- this.projectId = projectId;
22350
- this.database = database ? database : DEFAULT_DATABASE_NAME;
22351
- }
22352
- get isDefaultDatabase() {
22353
- return this.database === DEFAULT_DATABASE_NAME;
22354
- }
22355
- isEqual(other) {
22356
- return (other instanceof DatabaseId &&
22357
- other.projectId === this.projectId &&
22358
- other.database === this.database);
22359
- }
22360
- }
22361
-
22362
22487
  /**
22363
22488
  * @license
22364
22489
  * Copyright 2020 Google LLC
@@ -26272,17 +26397,6 @@ function writeBatch(firestore) {
26272
26397
  ensureFirestoreConfigured(firestore);
26273
26398
  return new WriteBatch(firestore, mutations => executeWrite(firestore, mutations));
26274
26399
  }
26275
- /** An index component consisting of field path and index type. */
26276
- class Segment {
26277
- constructor(
26278
- /** The field path of the component. */
26279
- fieldPath,
26280
- /** The fields sorting order. */
26281
- kind) {
26282
- this.fieldPath = fieldPath;
26283
- this.kind = kind;
26284
- }
26285
- }
26286
26400
 
26287
26401
  /**
26288
26402
  * @license
@@ -26306,27 +26420,29 @@ function setIndexConfiguration(firestore, jsonOrConfiguration) {
26306
26420
  const indexConfiguration = typeof jsonOrConfiguration === 'string'
26307
26421
  ? tryParseJson(jsonOrConfiguration)
26308
26422
  : jsonOrConfiguration;
26423
+ const parsedIndexes = [];
26309
26424
  // PORTING NOTE: We don't return an error if the user has not enabled
26310
26425
  // persistence since `enableIndexeddbPersistence()` can fail on the Web.
26311
26426
  if (Array.isArray(indexConfiguration.indexes)) {
26312
26427
  for (const index of indexConfiguration.indexes) {
26313
- tryGetString(index, 'collectionGroup');
26428
+ const collectionGroup = tryGetString(index, 'collectionGroup');
26314
26429
  const segments = [];
26315
26430
  if (Array.isArray(index.fields)) {
26316
26431
  for (const field of index.fields) {
26317
26432
  const fieldPathString = tryGetString(field, 'fieldPath');
26318
26433
  const fieldPath = fieldPathFromDotSeparatedString('setIndexConfiguration', fieldPathString);
26319
26434
  if (field.arrayConfig === 'CONTAINS') {
26320
- segments.push(new Segment(fieldPath, 2 /* CONTAINS */));
26435
+ segments.push(new IndexSegment(fieldPath, 2 /* CONTAINS */));
26321
26436
  }
26322
26437
  else if (field.order === 'ASCENDING') {
26323
- segments.push(new Segment(fieldPath, 0 /* ASCENDING */));
26438
+ segments.push(new IndexSegment(fieldPath, 0 /* ASCENDING */));
26324
26439
  }
26325
26440
  else if (field.order === 'DESCENDING') {
26326
- segments.push(new Segment(fieldPath, 1 /* DESCENDING */));
26441
+ segments.push(new IndexSegment(fieldPath, 1 /* DESCENDING */));
26327
26442
  }
26328
26443
  }
26329
26444
  }
26445
+ parsedIndexes.push(new FieldIndex(FieldIndex.UNKNOWN_ID, collectionGroup, segments, IndexState.empty()));
26330
26446
  }
26331
26447
  }
26332
26448
  // TODO(indexing): Configure indexes