@firebase/firestore 3.4.4-canary.222f264ff → 3.4.4-canary.6c8eabfc5

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 (112) hide show
  1. package/dist/firestore/src/api/{query.d.ts → filter.d.ts} +0 -0
  2. package/dist/firestore/src/api/snapshot.d.ts +1 -2
  3. package/dist/firestore/src/api.d.ts +1 -1
  4. package/dist/firestore/src/core/database_info.d.ts +1 -0
  5. package/dist/firestore/src/core/target.d.ts +34 -5
  6. package/dist/firestore/src/lite-api/query.d.ts +2 -2
  7. package/dist/firestore/src/local/index_manager.d.ts +52 -0
  8. package/dist/firestore/src/local/indexeddb_index_manager.d.ts +11 -0
  9. package/dist/firestore/src/local/indexeddb_schema.d.ts +121 -7
  10. package/dist/firestore/src/local/local_serializer.d.ts +1 -1
  11. package/dist/firestore/src/local/memory_index_manager.d.ts +11 -0
  12. package/dist/firestore/src/local/remote_document_change_buffer.d.ts +3 -12
  13. package/dist/firestore/src/local/simple_db.d.ts +1 -0
  14. package/dist/firestore/src/model/document.d.ts +7 -0
  15. package/dist/firestore/src/model/document_key.d.ts +1 -0
  16. package/dist/firestore/src/model/field_index.d.ts +87 -7
  17. package/dist/firestore/src/model/values.d.ts +7 -0
  18. package/dist/firestore/test/unit/local/test_remote_document_cache.d.ts +1 -1
  19. package/dist/firestore/test/unit/model/field_index.test.d.ts +17 -0
  20. package/dist/firestore/test/unit/model/target.test.d.ts +17 -0
  21. package/dist/firestore/test/util/helpers.d.ts +8 -2
  22. package/dist/index.d.ts +1 -2
  23. package/dist/index.esm2017.js +3451 -3194
  24. package/dist/index.esm2017.js.map +1 -1
  25. package/dist/index.esm5.js +3430 -3264
  26. package/dist/index.esm5.js.map +1 -1
  27. package/dist/index.node.cjs.js +543 -242
  28. package/dist/index.node.cjs.js.map +1 -1
  29. package/dist/index.node.mjs +543 -242
  30. package/dist/index.node.mjs.map +1 -1
  31. package/dist/index.rn.js +3520 -3301
  32. package/dist/index.rn.js.map +1 -1
  33. package/dist/internal.d.ts +183 -16
  34. package/dist/lite/firestore/src/api/{query.d.ts → filter.d.ts} +0 -0
  35. package/dist/lite/firestore/src/api/snapshot.d.ts +1 -2
  36. package/dist/lite/firestore/src/api.d.ts +1 -1
  37. package/dist/lite/firestore/src/core/database_info.d.ts +1 -0
  38. package/dist/lite/firestore/src/core/target.d.ts +34 -5
  39. package/dist/lite/firestore/src/lite-api/query.d.ts +2 -2
  40. package/dist/lite/firestore/src/local/index_manager.d.ts +52 -0
  41. package/dist/lite/firestore/src/local/indexeddb_index_manager.d.ts +11 -0
  42. package/dist/lite/firestore/src/local/indexeddb_schema.d.ts +121 -7
  43. package/dist/lite/firestore/src/local/local_serializer.d.ts +1 -1
  44. package/dist/lite/firestore/src/local/memory_index_manager.d.ts +11 -0
  45. package/dist/lite/firestore/src/local/remote_document_change_buffer.d.ts +3 -12
  46. package/dist/lite/firestore/src/local/simple_db.d.ts +1 -0
  47. package/dist/lite/firestore/src/model/document.d.ts +7 -0
  48. package/dist/lite/firestore/src/model/document_key.d.ts +1 -0
  49. package/dist/lite/firestore/src/model/field_index.d.ts +87 -7
  50. package/dist/lite/firestore/src/model/values.d.ts +7 -0
  51. package/dist/lite/firestore/test/unit/local/test_remote_document_cache.d.ts +1 -1
  52. package/dist/lite/firestore/test/unit/model/field_index.test.d.ts +17 -0
  53. package/dist/lite/firestore/test/unit/model/target.test.d.ts +17 -0
  54. package/dist/lite/firestore/test/util/helpers.d.ts +8 -2
  55. package/dist/lite/index.browser.esm2017.js +1166 -1152
  56. package/dist/lite/index.browser.esm2017.js.map +1 -1
  57. package/dist/lite/index.browser.esm5.js +367 -359
  58. package/dist/lite/index.browser.esm5.js.map +1 -1
  59. package/dist/lite/index.node.cjs.js +53 -34
  60. package/dist/lite/index.node.cjs.js.map +1 -1
  61. package/dist/lite/index.node.mjs +53 -34
  62. package/dist/lite/index.node.mjs.map +1 -1
  63. package/dist/lite/index.rn.esm2017.js +318 -304
  64. package/dist/lite/index.rn.esm2017.js.map +1 -1
  65. package/dist/lite/internal.d.ts +11 -2
  66. package/dist/lite/packages/firestore/dist/lite/index.browser.esm2017.d.ts +125 -124
  67. package/dist/lite/packages/firestore/src/api/{query.d.ts → filter.d.ts} +0 -0
  68. package/dist/lite/packages/firestore/src/api/snapshot.d.ts +1 -2
  69. package/dist/lite/packages/firestore/src/api.d.ts +1 -1
  70. package/dist/lite/packages/firestore/src/core/database_info.d.ts +1 -0
  71. package/dist/lite/packages/firestore/src/core/target.d.ts +34 -5
  72. package/dist/lite/packages/firestore/src/lite-api/query.d.ts +2 -2
  73. package/dist/lite/packages/firestore/src/local/index_manager.d.ts +52 -0
  74. package/dist/lite/packages/firestore/src/local/indexeddb_index_manager.d.ts +11 -0
  75. package/dist/lite/packages/firestore/src/local/indexeddb_schema.d.ts +121 -7
  76. package/dist/lite/packages/firestore/src/local/local_serializer.d.ts +1 -1
  77. package/dist/lite/packages/firestore/src/local/memory_index_manager.d.ts +11 -0
  78. package/dist/lite/packages/firestore/src/local/remote_document_change_buffer.d.ts +3 -12
  79. package/dist/lite/packages/firestore/src/local/simple_db.d.ts +1 -0
  80. package/dist/lite/packages/firestore/src/model/document.d.ts +7 -0
  81. package/dist/lite/packages/firestore/src/model/document_key.d.ts +1 -0
  82. package/dist/lite/packages/firestore/src/model/field_index.d.ts +87 -7
  83. package/dist/lite/packages/firestore/src/model/values.d.ts +7 -0
  84. package/dist/lite/packages/firestore/test/unit/local/test_remote_document_cache.d.ts +1 -1
  85. package/dist/lite/packages/firestore/test/unit/model/field_index.test.d.ts +17 -0
  86. package/dist/lite/packages/firestore/test/unit/model/target.test.d.ts +17 -0
  87. package/dist/lite/packages/firestore/test/util/helpers.d.ts +8 -2
  88. package/dist/lite/private.d.ts +9 -2
  89. package/dist/packages/firestore/dist/index.esm2017.d.ts +175 -173
  90. package/dist/packages/firestore/src/api/{query.d.ts → filter.d.ts} +0 -0
  91. package/dist/packages/firestore/src/api/snapshot.d.ts +1 -2
  92. package/dist/packages/firestore/src/api.d.ts +1 -1
  93. package/dist/packages/firestore/src/core/database_info.d.ts +1 -0
  94. package/dist/packages/firestore/src/core/target.d.ts +34 -5
  95. package/dist/packages/firestore/src/lite-api/query.d.ts +2 -2
  96. package/dist/packages/firestore/src/local/index_manager.d.ts +52 -0
  97. package/dist/packages/firestore/src/local/indexeddb_index_manager.d.ts +11 -0
  98. package/dist/packages/firestore/src/local/indexeddb_schema.d.ts +121 -7
  99. package/dist/packages/firestore/src/local/local_serializer.d.ts +1 -1
  100. package/dist/packages/firestore/src/local/memory_index_manager.d.ts +11 -0
  101. package/dist/packages/firestore/src/local/remote_document_change_buffer.d.ts +3 -12
  102. package/dist/packages/firestore/src/local/simple_db.d.ts +1 -0
  103. package/dist/packages/firestore/src/model/document.d.ts +7 -0
  104. package/dist/packages/firestore/src/model/document_key.d.ts +1 -0
  105. package/dist/packages/firestore/src/model/field_index.d.ts +87 -7
  106. package/dist/packages/firestore/src/model/values.d.ts +7 -0
  107. package/dist/packages/firestore/test/unit/local/test_remote_document_cache.d.ts +1 -1
  108. package/dist/packages/firestore/test/unit/model/field_index.test.d.ts +17 -0
  109. package/dist/packages/firestore/test/unit/model/target.test.d.ts +17 -0
  110. package/dist/packages/firestore/test/util/helpers.d.ts +8 -2
  111. package/dist/private.d.ts +181 -16
  112. 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.6c8eabfc5";
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.6-canary.6c8eabfc5";
69
69
 
70
70
  /**
71
71
  * @license
@@ -1196,23 +1196,6 @@ function decodeResourcePath(path) {
1196
1196
  }
1197
1197
  return new ResourcePath(segments);
1198
1198
  }
1199
-
1200
- /**
1201
- * @license
1202
- * Copyright 2017 Google LLC
1203
- *
1204
- * Licensed under the Apache License, Version 2.0 (the "License");
1205
- * you may not use this file except in compliance with the License.
1206
- * You may obtain a copy of the License at
1207
- *
1208
- * http://www.apache.org/licenses/LICENSE-2.0
1209
- *
1210
- * Unless required by applicable law or agreed to in writing, software
1211
- * distributed under the License is distributed on an "AS IS" BASIS,
1212
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1213
- * See the License for the specific language governing permissions and
1214
- * limitations under the License.
1215
- */
1216
1199
  /**
1217
1200
  * Schema Version for the Web client:
1218
1201
  * 1. Initial version including Mutation Queue, Query Cache, and Remote
@@ -1231,6 +1214,7 @@ function decodeResourcePath(path) {
1231
1214
  * an auto-incrementing ID. This is required for Index-Free queries.
1232
1215
  * 10. Rewrite the canonical IDs to the explicit Protobuf-based format.
1233
1216
  * 11. Add bundles and named_queries for bundle support.
1217
+ * 12. Add indexing support.
1234
1218
  */
1235
1219
  const SCHEMA_VERSION = 11;
1236
1220
  /**
@@ -1757,9 +1741,7 @@ class DbClientMetadata {
1757
1741
  DbClientMetadata.store = 'clientMetadata';
1758
1742
  /** Keys are automatically assigned via the clientId properties. */
1759
1743
  DbClientMetadata.keyPath = 'clientId';
1760
- /**
1761
- * A object representing a bundle loaded by the SDK.
1762
- */
1744
+ /** An object representing a bundle loaded by the SDK. */
1763
1745
  class DbBundle {
1764
1746
  constructor(
1765
1747
  /** The ID of the loaded bundle. */
@@ -1776,9 +1758,7 @@ class DbBundle {
1776
1758
  /** Name of the IndexedDb object store. */
1777
1759
  DbBundle.store = 'bundles';
1778
1760
  DbBundle.keyPath = 'bundleId';
1779
- /**
1780
- * A object representing a named query loaded by the SDK via a bundle.
1781
- */
1761
+ /** An object representing a named query loaded by the SDK via a bundle. */
1782
1762
  class DbNamedQuery {
1783
1763
  constructor(
1784
1764
  /** The name of the query. */
@@ -1795,6 +1775,93 @@ class DbNamedQuery {
1795
1775
  /** Name of the IndexedDb object store. */
1796
1776
  DbNamedQuery.store = 'namedQueries';
1797
1777
  DbNamedQuery.keyPath = 'name';
1778
+ /** An object representing the global configuration for a field index. */
1779
+ class DbIndexConfiguration {
1780
+ constructor(
1781
+ /** The index id for this entry. */
1782
+ indexId,
1783
+ /** The collection group this index belongs to. */
1784
+ collectionGroup,
1785
+ /** The fields to index for this index. */
1786
+ fields) {
1787
+ this.indexId = indexId;
1788
+ this.collectionGroup = collectionGroup;
1789
+ this.fields = fields;
1790
+ }
1791
+ }
1792
+ /** Name of the IndexedDb object store. */
1793
+ DbIndexConfiguration.store = 'indexConfiguration';
1794
+ DbIndexConfiguration.keyPath = 'indexId';
1795
+ /**
1796
+ * An object describing how up-to-date the index backfill is for each user and
1797
+ * index.
1798
+ */
1799
+ class DbIndexState {
1800
+ constructor(
1801
+ /** The index id for this entry. */
1802
+ indexId,
1803
+ /** The user id for this entry. */
1804
+ uid,
1805
+ /**
1806
+ * A number that indicates when the index was last updated (relative to
1807
+ * other indexes).
1808
+ */
1809
+ sequenceNumber,
1810
+ /**
1811
+ * The latest read time that has been indexed by Firestore for this field
1812
+ * index. Set to `{seconds: 0, nanos: 0}` if no documents have been indexed.
1813
+ */
1814
+ readTime,
1815
+ /**
1816
+ * The last document that has been indexed for this field index. Empty if
1817
+ * no documents have been indexed.
1818
+ */
1819
+ documentKey,
1820
+ /**
1821
+ * The largest mutation batch id that has been processed for this index. -1
1822
+ * if no mutations have been indexed.
1823
+ */
1824
+ largestBatchId) {
1825
+ this.indexId = indexId;
1826
+ this.uid = uid;
1827
+ this.sequenceNumber = sequenceNumber;
1828
+ this.readTime = readTime;
1829
+ this.documentKey = documentKey;
1830
+ this.largestBatchId = largestBatchId;
1831
+ }
1832
+ }
1833
+ /** Name of the IndexedDb object store. */
1834
+ DbIndexState.store = 'indexState';
1835
+ DbIndexState.keyPath = ['indexId', 'uid'];
1836
+ /** An object that stores the encoded entries for all documents and fields. */
1837
+ class DbIndexEntries {
1838
+ constructor(
1839
+ /** The index id for this entry. */
1840
+ indexId,
1841
+ /** The user id for this entry. */
1842
+ uid,
1843
+ /** The encoded array index value for this entry. */
1844
+ arrayValue,
1845
+ /** The encoded directional value for equality and inequality filters. */
1846
+ directionalValue,
1847
+ /** The document key this entry points to. */
1848
+ documentKey) {
1849
+ this.indexId = indexId;
1850
+ this.uid = uid;
1851
+ this.arrayValue = arrayValue;
1852
+ this.directionalValue = directionalValue;
1853
+ this.documentKey = documentKey;
1854
+ }
1855
+ }
1856
+ /** Name of the IndexedDb object store. */
1857
+ DbIndexEntries.store = 'indexEntries';
1858
+ DbIndexEntries.keyPath = [
1859
+ 'indexId',
1860
+ 'uid',
1861
+ 'arrayValue',
1862
+ 'directionalValue',
1863
+ 'documentKey'
1864
+ ];
1798
1865
  // Visible for testing
1799
1866
  const V1_STORES = [
1800
1867
  DbMutationQueue.store,
@@ -1809,7 +1876,6 @@ const V1_STORES = [
1809
1876
  // V2 is no longer usable (see comment at top of file)
1810
1877
  // Visible for testing
1811
1878
  const V3_STORES = V1_STORES;
1812
- // Visible for testing
1813
1879
  // Note: DbRemoteDocumentChanges is no longer used and dropped with v9.
1814
1880
  const V4_STORES = [...V3_STORES, DbClientMetadata.store];
1815
1881
  // V5 does not change the set of stores.
@@ -1819,6 +1885,12 @@ const V8_STORES = [...V6_STORES, DbCollectionParent.store];
1819
1885
  // V9 does not change the set of stores.
1820
1886
  // V10 does not change the set of stores.
1821
1887
  const V11_STORES = [...V8_STORES, DbBundle.store, DbNamedQuery.store];
1888
+ [
1889
+ ...V11_STORES,
1890
+ DbIndexConfiguration.store,
1891
+ DbIndexState.store,
1892
+ DbIndexEntries.store
1893
+ ];
1822
1894
  /**
1823
1895
  * The list of all default IndexedDB stores used throughout the SDK. This is
1824
1896
  * used when creating transactions so that access across all stores is done
@@ -2121,6 +2193,15 @@ class SimpleDbTransaction {
2121
2193
  this.transaction.abort();
2122
2194
  }
2123
2195
  }
2196
+ maybeCommit() {
2197
+ // If the browser supports V3 IndexedDB, we invoke commit() explicitly to
2198
+ // speed up index DB processing if the event loop remains blocks.
2199
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2200
+ const maybeV3IndexedDb = this.transaction;
2201
+ if (!this.aborted && typeof maybeV3IndexedDb.commit === 'function') {
2202
+ maybeV3IndexedDb.commit();
2203
+ }
2204
+ }
2124
2205
  /**
2125
2206
  * Returns a SimpleDbStore<KeyType, ValueType> for the specified store. All
2126
2207
  * operations performed on the SimpleDbStore happen within the context of this
@@ -2317,6 +2398,10 @@ class SimpleDb {
2317
2398
  this.db = await this.ensureDb(action);
2318
2399
  const transaction = SimpleDbTransaction.open(this.db, action, readonly ? 'readonly' : 'readwrite', objectStores);
2319
2400
  const transactionFnResult = transactionFn(transaction)
2401
+ .next(result => {
2402
+ transaction.maybeCommit();
2403
+ return result;
2404
+ })
2320
2405
  .catch(error => {
2321
2406
  // Abort the transaction if there was an error.
2322
2407
  transaction.abort(error);
@@ -3378,6 +3463,75 @@ function getLocalWriteTime(value) {
3378
3463
  return new Timestamp(localWriteTime.seconds, localWriteTime.nanos);
3379
3464
  }
3380
3465
 
3466
+ /**
3467
+ * @license
3468
+ * Copyright 2017 Google LLC
3469
+ *
3470
+ * Licensed under the Apache License, Version 2.0 (the "License");
3471
+ * you may not use this file except in compliance with the License.
3472
+ * You may obtain a copy of the License at
3473
+ *
3474
+ * http://www.apache.org/licenses/LICENSE-2.0
3475
+ *
3476
+ * Unless required by applicable law or agreed to in writing, software
3477
+ * distributed under the License is distributed on an "AS IS" BASIS,
3478
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3479
+ * See the License for the specific language governing permissions and
3480
+ * limitations under the License.
3481
+ */
3482
+ class DatabaseInfo {
3483
+ /**
3484
+ * Constructs a DatabaseInfo using the provided host, databaseId and
3485
+ * persistenceKey.
3486
+ *
3487
+ * @param databaseId - The database to use.
3488
+ * @param appId - The Firebase App Id.
3489
+ * @param persistenceKey - A unique identifier for this Firestore's local
3490
+ * storage (used in conjunction with the databaseId).
3491
+ * @param host - The Firestore backend host to connect to.
3492
+ * @param ssl - Whether to use SSL when connecting.
3493
+ * @param forceLongPolling - Whether to use the forceLongPolling option
3494
+ * when using WebChannel as the network transport.
3495
+ * @param autoDetectLongPolling - Whether to use the detectBufferingProxy
3496
+ * option when using WebChannel as the network transport.
3497
+ * @param useFetchStreams Whether to use the Fetch API instead of
3498
+ * XMLHTTPRequest
3499
+ */
3500
+ constructor(databaseId, appId, persistenceKey, host, ssl, forceLongPolling, autoDetectLongPolling, useFetchStreams) {
3501
+ this.databaseId = databaseId;
3502
+ this.appId = appId;
3503
+ this.persistenceKey = persistenceKey;
3504
+ this.host = host;
3505
+ this.ssl = ssl;
3506
+ this.forceLongPolling = forceLongPolling;
3507
+ this.autoDetectLongPolling = autoDetectLongPolling;
3508
+ this.useFetchStreams = useFetchStreams;
3509
+ }
3510
+ }
3511
+ /** The default database name for a project. */
3512
+ const DEFAULT_DATABASE_NAME = '(default)';
3513
+ /**
3514
+ * Represents the database ID a Firestore client is associated with.
3515
+ * @internal
3516
+ */
3517
+ class DatabaseId {
3518
+ constructor(projectId, database) {
3519
+ this.projectId = projectId;
3520
+ this.database = database ? database : DEFAULT_DATABASE_NAME;
3521
+ }
3522
+ static empty() {
3523
+ return new DatabaseId('', '');
3524
+ }
3525
+ get isDefaultDatabase() {
3526
+ return this.database === DEFAULT_DATABASE_NAME;
3527
+ }
3528
+ isEqual(other) {
3529
+ return (other instanceof DatabaseId &&
3530
+ other.projectId === this.projectId &&
3531
+ other.database === this.database);
3532
+ }
3533
+ }
3534
+
3381
3535
  /**
3382
3536
  * @license
3383
3537
  * Copyright 2017 Google LLC
@@ -3449,6 +3603,9 @@ class DocumentKey {
3449
3603
  static fromName(name) {
3450
3604
  return new DocumentKey(ResourcePath.fromString(name).popFirst(5));
3451
3605
  }
3606
+ static empty() {
3607
+ return new DocumentKey(ResourcePath.emptyPath());
3608
+ }
3452
3609
  /** Returns true if the document is in the specified collectionId. */
3453
3610
  hasCollectionId(collectionId) {
3454
3611
  return (this.path.length >= 2 &&
@@ -4097,10 +4254,11 @@ function extractFieldMask(value) {
4097
4254
  * from all views.
4098
4255
  */
4099
4256
  class MutableDocument {
4100
- constructor(key, documentType, version, data, documentState) {
4257
+ constructor(key, documentType, version, readTime, data, documentState) {
4101
4258
  this.key = key;
4102
4259
  this.documentType = documentType;
4103
4260
  this.version = version;
4261
+ this.readTime = readTime;
4104
4262
  this.data = data;
4105
4263
  this.documentState = documentState;
4106
4264
  }
@@ -4109,18 +4267,18 @@ class MutableDocument {
4109
4267
  * base document for mutations.
4110
4268
  */
4111
4269
  static newInvalidDocument(documentKey) {
4112
- return new MutableDocument(documentKey, 0 /* INVALID */, SnapshotVersion.min(), ObjectValue.empty(), 0 /* SYNCED */);
4270
+ return new MutableDocument(documentKey, 0 /* INVALID */, SnapshotVersion.min(), SnapshotVersion.min(), ObjectValue.empty(), 0 /* SYNCED */);
4113
4271
  }
4114
4272
  /**
4115
4273
  * Creates a new document that is known to exist with the given data at the
4116
4274
  * given version.
4117
4275
  */
4118
4276
  static newFoundDocument(documentKey, version, value) {
4119
- return new MutableDocument(documentKey, 1 /* FOUND_DOCUMENT */, version, value, 0 /* SYNCED */);
4277
+ return new MutableDocument(documentKey, 1 /* FOUND_DOCUMENT */, version, SnapshotVersion.min(), value, 0 /* SYNCED */);
4120
4278
  }
4121
4279
  /** Creates a new document that is known to not exist at the given version. */
4122
4280
  static newNoDocument(documentKey, version) {
4123
- return new MutableDocument(documentKey, 2 /* NO_DOCUMENT */, version, ObjectValue.empty(), 0 /* SYNCED */);
4281
+ return new MutableDocument(documentKey, 2 /* NO_DOCUMENT */, version, SnapshotVersion.min(), ObjectValue.empty(), 0 /* SYNCED */);
4124
4282
  }
4125
4283
  /**
4126
4284
  * Creates a new document that is known to exist at the given version but
@@ -4128,7 +4286,7 @@ class MutableDocument {
4128
4286
  * base document).
4129
4287
  */
4130
4288
  static newUnknownDocument(documentKey, version) {
4131
- return new MutableDocument(documentKey, 3 /* UNKNOWN_DOCUMENT */, version, ObjectValue.empty(), 2 /* HAS_COMMITTED_MUTATIONS */);
4289
+ return new MutableDocument(documentKey, 3 /* UNKNOWN_DOCUMENT */, version, SnapshotVersion.min(), ObjectValue.empty(), 2 /* HAS_COMMITTED_MUTATIONS */);
4132
4290
  }
4133
4291
  /**
4134
4292
  * Changes the document type to indicate that it exists and that its version
@@ -4172,6 +4330,10 @@ class MutableDocument {
4172
4330
  this.documentState = 1 /* HAS_LOCAL_MUTATIONS */;
4173
4331
  return this;
4174
4332
  }
4333
+ setReadTime(readTime) {
4334
+ this.readTime = readTime;
4335
+ return this;
4336
+ }
4175
4337
  get hasLocalMutations() {
4176
4338
  return this.documentState === 1 /* HAS_LOCAL_MUTATIONS */;
4177
4339
  }
@@ -4202,7 +4364,7 @@ class MutableDocument {
4202
4364
  this.data.isEqual(other.data));
4203
4365
  }
4204
4366
  mutableCopy() {
4205
- return new MutableDocument(this.key, this.documentType, this.version, this.data.clone(), this.documentState);
4367
+ return new MutableDocument(this.key, this.documentType, this.version, this.readTime, this.data.clone(), this.documentState);
4206
4368
  }
4207
4369
  toString() {
4208
4370
  return (`Document(${this.key}, ${this.version}, ${JSON.stringify(this.data.value)}, ` +
@@ -4225,6 +4387,125 @@ function compareDocumentsByField(field, d1, d2) {
4225
4387
  }
4226
4388
  }
4227
4389
 
4390
+ /**
4391
+ * @license
4392
+ * Copyright 2021 Google LLC
4393
+ *
4394
+ * Licensed under the Apache License, Version 2.0 (the "License");
4395
+ * you may not use this file except in compliance with the License.
4396
+ * You may obtain a copy of the License at
4397
+ *
4398
+ * http://www.apache.org/licenses/LICENSE-2.0
4399
+ *
4400
+ * Unless required by applicable law or agreed to in writing, software
4401
+ * distributed under the License is distributed on an "AS IS" BASIS,
4402
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4403
+ * See the License for the specific language governing permissions and
4404
+ * limitations under the License.
4405
+ */
4406
+ /**
4407
+ * The initial mutation batch id for each index. Gets updated during index
4408
+ * backfill.
4409
+ */
4410
+ const INITIAL_LARGEST_BATCH_ID = -1;
4411
+ /**
4412
+ * The initial sequence number for each index. Gets updated during index
4413
+ * backfill.
4414
+ */
4415
+ const INITIAL_SEQUENCE_NUMBER = 0;
4416
+ /**
4417
+ * An index definition for field indexes in Firestore.
4418
+ *
4419
+ * Every index is associated with a collection. The definition contains a list
4420
+ * of fields and their index kind (which can be `ASCENDING`, `DESCENDING` or
4421
+ * `CONTAINS` for ArrayContains/ArrayContainsAny queries).
4422
+ *
4423
+ * Unlike the backend, the SDK does not differentiate between collection or
4424
+ * collection group-scoped indices. Every index can be used for both single
4425
+ * collection and collection group queries.
4426
+ */
4427
+ class FieldIndex {
4428
+ constructor(
4429
+ /**
4430
+ * The index ID. Returns -1 if the index ID is not available (e.g. the index
4431
+ * has not yet been persisted).
4432
+ */
4433
+ indexId,
4434
+ /** The collection ID this index applies to. */
4435
+ collectionGroup,
4436
+ /** The field segments for this index. */
4437
+ segments,
4438
+ /** Shows how up-to-date the index is for the current user. */
4439
+ indexState) {
4440
+ this.indexId = indexId;
4441
+ this.collectionGroup = collectionGroup;
4442
+ this.segments = segments;
4443
+ this.indexState = indexState;
4444
+ }
4445
+ }
4446
+ /** An ID for an index that has not yet been added to persistence. */
4447
+ FieldIndex.UNKNOWN_ID = -1;
4448
+ /** An index component consisting of field path and index type. */
4449
+ class IndexSegment {
4450
+ constructor(
4451
+ /** The field path of the component. */
4452
+ fieldPath,
4453
+ /** The fields sorting order. */
4454
+ kind) {
4455
+ this.fieldPath = fieldPath;
4456
+ this.kind = kind;
4457
+ }
4458
+ }
4459
+ /**
4460
+ * Stores the "high water mark" that indicates how updated the Index is for the
4461
+ * current user.
4462
+ */
4463
+ class IndexState {
4464
+ constructor(
4465
+ /**
4466
+ * Indicates when the index was last updated (relative to other indexes).
4467
+ */
4468
+ sequenceNumber,
4469
+ /** The the latest indexed read time, document and batch id. */
4470
+ offset) {
4471
+ this.sequenceNumber = sequenceNumber;
4472
+ this.offset = offset;
4473
+ }
4474
+ /** The state of an index that has not yet been backfilled. */
4475
+ static empty() {
4476
+ return new IndexState(INITIAL_SEQUENCE_NUMBER, IndexOffset.min());
4477
+ }
4478
+ }
4479
+ /**
4480
+ * Stores the latest read time, document and batch ID that were processed for an
4481
+ * index.
4482
+ */
4483
+ class IndexOffset {
4484
+ constructor(
4485
+ /**
4486
+ * The latest read time version that has been indexed by Firestore for this
4487
+ * field index.
4488
+ */
4489
+ readTime,
4490
+ /**
4491
+ * The key of the last document that was indexed for this query. Use
4492
+ * `DocumentKey.empty()` if no document has been indexed.
4493
+ */
4494
+ documentKey,
4495
+ /*
4496
+ * The largest mutation batch id that's been processed by Firestore.
4497
+ */
4498
+ largestBatchId) {
4499
+ this.readTime = readTime;
4500
+ this.documentKey = documentKey;
4501
+ this.largestBatchId = largestBatchId;
4502
+ }
4503
+ /** The state of an index that has not yet been backfilled. */
4504
+ static min() {
4505
+ return new IndexOffset(SnapshotVersion.min(), DocumentKey.empty(), INITIAL_LARGEST_BATCH_ID);
4506
+ }
4507
+ }
4508
+
4228
4509
  /**
4229
4510
  * @license
4230
4511
  * Copyright 2019 Google LLC
@@ -4268,27 +4549,29 @@ function newTarget(path, collectionGroup = null, orderBy = [], filters = [], lim
4268
4549
  function canonifyTarget(target) {
4269
4550
  const targetImpl = debugCast(target);
4270
4551
  if (targetImpl.memoizedCanonicalId === null) {
4271
- let canonicalId = targetImpl.path.canonicalString();
4552
+ let str = targetImpl.path.canonicalString();
4272
4553
  if (targetImpl.collectionGroup !== null) {
4273
- canonicalId += '|cg:' + targetImpl.collectionGroup;
4554
+ str += '|cg:' + targetImpl.collectionGroup;
4274
4555
  }
4275
- canonicalId += '|f:';
4276
- canonicalId += targetImpl.filters.map(f => canonifyFilter(f)).join(',');
4277
- canonicalId += '|ob:';
4278
- canonicalId += targetImpl.orderBy.map(o => canonifyOrderBy(o)).join(',');
4556
+ str += '|f:';
4557
+ str += targetImpl.filters.map(f => canonifyFilter(f)).join(',');
4558
+ str += '|ob:';
4559
+ str += targetImpl.orderBy.map(o => canonifyOrderBy(o)).join(',');
4279
4560
  if (!isNullOrUndefined(targetImpl.limit)) {
4280
- canonicalId += '|l:';
4281
- canonicalId += targetImpl.limit;
4561
+ str += '|l:';
4562
+ str += targetImpl.limit;
4282
4563
  }
4283
4564
  if (targetImpl.startAt) {
4284
- canonicalId += '|lb:';
4285
- canonicalId += canonifyBound(targetImpl.startAt);
4565
+ str += '|lb:';
4566
+ str += targetImpl.startAt.inclusive ? 'b:' : 'a:';
4567
+ str += targetImpl.startAt.position.map(p => canonicalId(p)).join(',');
4286
4568
  }
4287
4569
  if (targetImpl.endAt) {
4288
- canonicalId += '|ub:';
4289
- canonicalId += canonifyBound(targetImpl.endAt);
4570
+ str += '|ub:';
4571
+ str += targetImpl.endAt.inclusive ? 'a:' : 'b:';
4572
+ str += targetImpl.endAt.position.map(p => canonicalId(p)).join(',');
4290
4573
  }
4291
- targetImpl.memoizedCanonicalId = canonicalId;
4574
+ targetImpl.memoizedCanonicalId = str;
4292
4575
  }
4293
4576
  return targetImpl.memoizedCanonicalId;
4294
4577
  }
@@ -4311,10 +4594,14 @@ function stringifyTarget(target) {
4311
4594
  .join(', ')}]`;
4312
4595
  }
4313
4596
  if (target.startAt) {
4314
- str += ', startAt: ' + canonifyBound(target.startAt);
4597
+ str += ', startAt: ';
4598
+ str += target.startAt.inclusive ? 'b:' : 'a:';
4599
+ str += target.startAt.position.map(p => canonicalId(p)).join(',');
4315
4600
  }
4316
4601
  if (target.endAt) {
4317
- str += ', endAt: ' + canonifyBound(target.endAt);
4602
+ str += ', endAt: ';
4603
+ str += target.endAt.inclusive ? 'a:' : 'b:';
4604
+ str += target.endAt.position.map(p => canonicalId(p)).join(',');
4318
4605
  }
4319
4606
  return `Target(${str})`;
4320
4607
  }
@@ -4349,7 +4636,7 @@ function targetEquals(left, right) {
4349
4636
  }
4350
4637
  return boundEquals(left.endAt, right.endAt);
4351
4638
  }
4352
- function isDocumentTarget(target) {
4639
+ function targetIsDocumentTarget(target) {
4353
4640
  return (DocumentKey.isDocumentKey(target.path) &&
4354
4641
  target.collectionGroup === null &&
4355
4642
  target.filters.length === 0);
@@ -4552,17 +4839,11 @@ class ArrayContainsAnyFilter extends FieldFilter {
4552
4839
  * just after the provided values.
4553
4840
  */
4554
4841
  class Bound {
4555
- constructor(position, before) {
4842
+ constructor(position, inclusive) {
4556
4843
  this.position = position;
4557
- this.before = before;
4844
+ this.inclusive = inclusive;
4558
4845
  }
4559
4846
  }
4560
- function canonifyBound(bound) {
4561
- // TODO(b/29183165): Make this collision robust.
4562
- return `${bound.before ? 'b' : 'a'}:${bound.position
4563
- .map(p => canonicalId(p))
4564
- .join(',')}`;
4565
- }
4566
4847
  /**
4567
4848
  * An ordering on a field, in some Direction. Direction defaults to ASCENDING.
4568
4849
  */
@@ -4582,11 +4863,7 @@ function stringifyOrderBy(orderBy) {
4582
4863
  function orderByEquals(left, right) {
4583
4864
  return left.dir === right.dir && left.field.isEqual(right.field);
4584
4865
  }
4585
- /**
4586
- * Returns true if a document sorts before a bound using the provided sort
4587
- * order.
4588
- */
4589
- function sortsBeforeDocument(bound, orderBy, doc) {
4866
+ function boundCompareToDocument(bound, orderBy, doc) {
4590
4867
  let comparison = 0;
4591
4868
  for (let i = 0; i < bound.position.length; i++) {
4592
4869
  const orderByComponent = orderBy[i];
@@ -4605,7 +4882,23 @@ function sortsBeforeDocument(bound, orderBy, doc) {
4605
4882
  break;
4606
4883
  }
4607
4884
  }
4608
- return bound.before ? comparison <= 0 : comparison < 0;
4885
+ return comparison;
4886
+ }
4887
+ /**
4888
+ * Returns true if a document sorts after a bound using the provided sort
4889
+ * order.
4890
+ */
4891
+ function boundSortsAfterDocument(bound, orderBy, doc) {
4892
+ const comparison = boundCompareToDocument(bound, orderBy, doc);
4893
+ return bound.inclusive ? comparison >= 0 : comparison > 0;
4894
+ }
4895
+ /**
4896
+ * Returns true if a document sorts before a bound using the provided sort
4897
+ * order.
4898
+ */
4899
+ function boundSortsBeforeDocument(bound, orderBy, doc) {
4900
+ const comparison = boundCompareToDocument(bound, orderBy, doc);
4901
+ return bound.inclusive ? comparison <= 0 : comparison < 0;
4609
4902
  }
4610
4903
  function boundEquals(left, right) {
4611
4904
  if (left === null) {
@@ -4614,7 +4907,7 @@ function boundEquals(left, right) {
4614
4907
  else if (right === null) {
4615
4908
  return false;
4616
4909
  }
4617
- if (left.before !== right.before ||
4910
+ if (left.inclusive !== right.inclusive ||
4618
4911
  left.position.length !== right.position.length) {
4619
4912
  return false;
4620
4913
  }
@@ -4818,10 +5111,10 @@ function queryToTarget(query) {
4818
5111
  }
4819
5112
  // We need to swap the cursors to match the now-flipped query ordering.
4820
5113
  const startAt = queryImpl.endAt
4821
- ? new Bound(queryImpl.endAt.position, !queryImpl.endAt.before)
5114
+ ? new Bound(queryImpl.endAt.position, !queryImpl.endAt.inclusive)
4822
5115
  : null;
4823
5116
  const endAt = queryImpl.startAt
4824
- ? new Bound(queryImpl.startAt.position, !queryImpl.startAt.before)
5117
+ ? new Bound(queryImpl.startAt.position, !queryImpl.startAt.inclusive)
4825
5118
  : null;
4826
5119
  // Now return as a LimitType.First query.
4827
5120
  queryImpl.memoizedTarget = newTarget(queryImpl.path, queryImpl.collectionGroup, orderBys, queryImpl.filters, queryImpl.limit, startAt, endAt);
@@ -4909,11 +5202,11 @@ function queryMatchesFilters(query, doc) {
4909
5202
  /** Makes sure a document is within the bounds, if provided. */
4910
5203
  function queryMatchesBounds(query, doc) {
4911
5204
  if (query.startAt &&
4912
- !sortsBeforeDocument(query.startAt, queryOrderBy(query), doc)) {
5205
+ !boundSortsBeforeDocument(query.startAt, queryOrderBy(query), doc)) {
4913
5206
  return false;
4914
5207
  }
4915
5208
  if (query.endAt &&
4916
- sortsBeforeDocument(query.endAt, queryOrderBy(query), doc)) {
5209
+ !boundSortsAfterDocument(query.endAt, queryOrderBy(query), doc)) {
4917
5210
  return false;
4918
5211
  }
4919
5212
  return true;
@@ -6994,7 +7287,7 @@ class WatchChangeAggregator {
6994
7287
  const targetData = this.targetDataForActiveTarget(targetId);
6995
7288
  if (targetData) {
6996
7289
  const target = targetData.target;
6997
- if (isDocumentTarget(target)) {
7290
+ if (targetIsDocumentTarget(target)) {
6998
7291
  if (expectedCount === 0) {
6999
7292
  // The existence filter told us the document does not exist. We deduce
7000
7293
  // that this document does not exist and apply a deleted document to
@@ -7029,7 +7322,7 @@ class WatchChangeAggregator {
7029
7322
  this.targetStates.forEach((targetState, targetId) => {
7030
7323
  const targetData = this.targetDataForActiveTarget(targetId);
7031
7324
  if (targetData) {
7032
- if (targetState.current && isDocumentTarget(targetData.target)) {
7325
+ if (targetState.current && targetIsDocumentTarget(targetData.target)) {
7033
7326
  // Document queries for document that don't exist can produce an empty
7034
7327
  // result set. To update our local cache, we synthesize a document
7035
7328
  // delete if we have not previously received the document. This
@@ -7072,6 +7365,7 @@ class WatchChangeAggregator {
7072
7365
  resolvedLimboDocuments = resolvedLimboDocuments.add(key);
7073
7366
  }
7074
7367
  });
7368
+ this.pendingDocumentUpdates.forEach((_, doc) => doc.setReadTime(snapshotVersion));
7075
7369
  const remoteEvent = new RemoteEvent(snapshotVersion, targetChanges, this.pendingTargetResets, this.pendingDocumentUpdates, resolvedLimboDocuments);
7076
7370
  this.pendingDocumentUpdates = mutableDocumentMap();
7077
7371
  this.pendingDocumentTargetMapping = documentTargetMap();
@@ -7791,10 +8085,10 @@ function toQueryTarget(serializer, target) {
7791
8085
  result.structuredQuery.limit = limit;
7792
8086
  }
7793
8087
  if (target.startAt) {
7794
- result.structuredQuery.startAt = toCursor(target.startAt);
8088
+ result.structuredQuery.startAt = toStartAtCursor(target.startAt);
7795
8089
  }
7796
8090
  if (target.endAt) {
7797
- result.structuredQuery.endAt = toCursor(target.endAt);
8091
+ result.structuredQuery.endAt = toEndAtCursor(target.endAt);
7798
8092
  }
7799
8093
  return result;
7800
8094
  }
@@ -7827,11 +8121,11 @@ function convertQueryTargetToQuery(target) {
7827
8121
  }
7828
8122
  let startAt = null;
7829
8123
  if (query.startAt) {
7830
- startAt = fromCursor(query.startAt);
8124
+ startAt = fromStartAtCursor(query.startAt);
7831
8125
  }
7832
8126
  let endAt = null;
7833
8127
  if (query.endAt) {
7834
- endAt = fromCursor(query.endAt);
8128
+ endAt = fromEndAtCursor(query.endAt);
7835
8129
  }
7836
8130
  return newQuery(path, collectionGroup, orderBy, filterBy, limit, "F" /* First */, startAt, endAt);
7837
8131
  }
@@ -7864,7 +8158,7 @@ function toLabel(serializer, purpose) {
7864
8158
  function toTarget(serializer, targetData) {
7865
8159
  let result;
7866
8160
  const target = targetData.target;
7867
- if (isDocumentTarget(target)) {
8161
+ if (targetIsDocumentTarget(target)) {
7868
8162
  result = { documents: toDocumentsTarget(serializer, target) };
7869
8163
  }
7870
8164
  else {
@@ -7922,16 +8216,27 @@ function toOrder(orderBys) {
7922
8216
  function fromOrder(orderBys) {
7923
8217
  return orderBys.map(order => fromPropertyOrder(order));
7924
8218
  }
7925
- function toCursor(cursor) {
8219
+ function toStartAtCursor(cursor) {
8220
+ return {
8221
+ before: cursor.inclusive,
8222
+ values: cursor.position
8223
+ };
8224
+ }
8225
+ function toEndAtCursor(cursor) {
7926
8226
  return {
7927
- before: cursor.before,
8227
+ before: !cursor.inclusive,
7928
8228
  values: cursor.position
7929
8229
  };
7930
8230
  }
7931
- function fromCursor(cursor) {
7932
- const before = !!cursor.before;
8231
+ function fromStartAtCursor(cursor) {
8232
+ const inclusive = !!cursor.before;
7933
8233
  const position = cursor.values || [];
7934
- return new Bound(position, before);
8234
+ return new Bound(position, inclusive);
8235
+ }
8236
+ function fromEndAtCursor(cursor) {
8237
+ const inclusive = !cursor.before;
8238
+ const position = cursor.values || [];
8239
+ return new Bound(position, inclusive);
7935
8240
  }
7936
8241
  // visible for testing
7937
8242
  function toDirection(dir) {
@@ -8192,29 +8497,34 @@ class LocalSerializer {
8192
8497
  }
8193
8498
  /** Decodes a remote document from storage locally to a Document. */
8194
8499
  function fromDbRemoteDocument(localSerializer, remoteDoc) {
8500
+ let doc;
8195
8501
  if (remoteDoc.document) {
8196
- return fromDocument(localSerializer.remoteSerializer, remoteDoc.document, !!remoteDoc.hasCommittedMutations);
8502
+ doc = fromDocument(localSerializer.remoteSerializer, remoteDoc.document, !!remoteDoc.hasCommittedMutations);
8197
8503
  }
8198
8504
  else if (remoteDoc.noDocument) {
8199
8505
  const key = DocumentKey.fromSegments(remoteDoc.noDocument.path);
8200
8506
  const version = fromDbTimestamp(remoteDoc.noDocument.readTime);
8201
- const document = MutableDocument.newNoDocument(key, version);
8202
- return remoteDoc.hasCommittedMutations
8203
- ? document.setHasCommittedMutations()
8204
- : document;
8507
+ doc = MutableDocument.newNoDocument(key, version);
8508
+ if (remoteDoc.hasCommittedMutations) {
8509
+ doc.setHasCommittedMutations();
8510
+ }
8205
8511
  }
8206
8512
  else if (remoteDoc.unknownDocument) {
8207
8513
  const key = DocumentKey.fromSegments(remoteDoc.unknownDocument.path);
8208
8514
  const version = fromDbTimestamp(remoteDoc.unknownDocument.version);
8209
- return MutableDocument.newUnknownDocument(key, version);
8515
+ doc = MutableDocument.newUnknownDocument(key, version);
8210
8516
  }
8211
8517
  else {
8212
8518
  return fail();
8213
8519
  }
8520
+ if (remoteDoc.readTime) {
8521
+ doc.setReadTime(fromDbTimestampKey(remoteDoc.readTime));
8522
+ }
8523
+ return doc;
8214
8524
  }
8215
8525
  /** Encodes a document for storage locally. */
8216
- function toDbRemoteDocument(localSerializer, document, readTime) {
8217
- const dbReadTime = toDbTimestampKey(readTime);
8526
+ function toDbRemoteDocument(localSerializer, document) {
8527
+ const dbReadTime = toDbTimestampKey(document.readTime);
8218
8528
  const parentPath = document.key.path.popLast().toArray();
8219
8529
  if (document.isFoundDocument()) {
8220
8530
  const doc = toDocument(localSerializer.remoteSerializer, document);
@@ -8225,10 +8535,10 @@ function toDbRemoteDocument(localSerializer, document, readTime) {
8225
8535
  }
8226
8536
  else if (document.isNoDocument()) {
8227
8537
  const path = document.key.path.toArray();
8228
- const readTime = toDbTimestamp(document.version);
8538
+ const version = toDbTimestamp(document.version);
8229
8539
  const hasCommittedMutations = document.hasCommittedMutations;
8230
8540
  return new DbRemoteDocument(
8231
- /* unknownDocument= */ null, new DbNoDocument(path, readTime),
8541
+ /* unknownDocument= */ null, new DbNoDocument(path, version),
8232
8542
  /* document= */ null, hasCommittedMutations, dbReadTime, parentPath);
8233
8543
  }
8234
8544
  else if (document.isUnknownDocument()) {
@@ -8309,7 +8619,7 @@ function toDbTarget(localSerializer, targetData) {
8309
8619
  const dbTimestamp = toDbTimestamp(targetData.snapshotVersion);
8310
8620
  const dbLastLimboFreeTimestamp = toDbTimestamp(targetData.lastLimboFreeSnapshotVersion);
8311
8621
  let queryProto;
8312
- if (isDocumentTarget(targetData.target)) {
8622
+ if (targetIsDocumentTarget(targetData.target)) {
8313
8623
  queryProto = toDocumentsTarget(localSerializer.remoteSerializer, targetData.target);
8314
8624
  }
8315
8625
  else {
@@ -8479,6 +8789,38 @@ class MemoryIndexManager {
8479
8789
  getCollectionParents(transaction, collectionId) {
8480
8790
  return PersistencePromise.resolve(this.collectionParentIndex.getEntries(collectionId));
8481
8791
  }
8792
+ addFieldIndex(transaction, index) {
8793
+ // Field indices are not supported with memory persistence.
8794
+ return PersistencePromise.resolve();
8795
+ }
8796
+ deleteFieldIndex(transaction, index) {
8797
+ // Field indices are not supported with memory persistence.
8798
+ return PersistencePromise.resolve();
8799
+ }
8800
+ getDocumentsMatchingTarget(transaction, fieldIndex, target) {
8801
+ // Field indices are not supported with memory persistence.
8802
+ return PersistencePromise.resolve(documentKeySet());
8803
+ }
8804
+ getFieldIndex(transaction, target) {
8805
+ // Field indices are not supported with memory persistence.
8806
+ return PersistencePromise.resolve(null);
8807
+ }
8808
+ getFieldIndexes(transaction, collectionGroup) {
8809
+ // Field indices are not supported with memory persistence.
8810
+ return PersistencePromise.resolve([]);
8811
+ }
8812
+ getNextCollectionGroupToUpdate(transaction) {
8813
+ // Field indices are not supported with memory persistence.
8814
+ return PersistencePromise.resolve(null);
8815
+ }
8816
+ updateCollectionGroup(transaction, collectionGroup, offset) {
8817
+ // Field indices are not supported with memory persistence.
8818
+ return PersistencePromise.resolve();
8819
+ }
8820
+ updateIndexEntries(transaction, documents) {
8821
+ // Field indices are not supported with memory persistence.
8822
+ return PersistencePromise.resolve();
8823
+ }
8482
8824
  }
8483
8825
  /**
8484
8826
  * Internal implementation of the collection-parent index exposed by MemoryIndexManager.
@@ -8587,6 +8929,38 @@ class IndexedDbIndexManager {
8587
8929
  return parentPaths;
8588
8930
  });
8589
8931
  }
8932
+ addFieldIndex(transaction, index) {
8933
+ // TODO(indexing): Implement
8934
+ return PersistencePromise.resolve();
8935
+ }
8936
+ deleteFieldIndex(transaction, index) {
8937
+ // TODO(indexing): Implement
8938
+ return PersistencePromise.resolve();
8939
+ }
8940
+ getDocumentsMatchingTarget(transaction, fieldIndex, target) {
8941
+ // TODO(indexing): Implement
8942
+ return PersistencePromise.resolve(documentKeySet());
8943
+ }
8944
+ getFieldIndex(transaction, target) {
8945
+ // TODO(indexing): Implement
8946
+ return PersistencePromise.resolve(null);
8947
+ }
8948
+ getFieldIndexes(transaction, collectionGroup) {
8949
+ // TODO(indexing): Implement
8950
+ return PersistencePromise.resolve([]);
8951
+ }
8952
+ getNextCollectionGroupToUpdate(transaction) {
8953
+ // TODO(indexing): Implement
8954
+ return PersistencePromise.resolve(null);
8955
+ }
8956
+ updateCollectionGroup(transaction, collectionGroup, offset) {
8957
+ // TODO(indexing): Implement
8958
+ return PersistencePromise.resolve();
8959
+ }
8960
+ updateIndexEntries(transaction, documents) {
8961
+ // TODO(indexing): Implement
8962
+ return PersistencePromise.resolve();
8963
+ }
8590
8964
  }
8591
8965
  /**
8592
8966
  * Helper to get a typed SimpleDbStore for the collectionParents
@@ -9757,7 +10131,7 @@ class IndexedDbLruDelegateImpl {
9757
10131
  // Our size accounting requires us to read all documents before
9758
10132
  // removing them.
9759
10133
  return changeBuffer.getEntry(txn, docKey).next(() => {
9760
- changeBuffer.removeEntry(docKey);
10134
+ changeBuffer.removeEntry(docKey, SnapshotVersion.min());
9761
10135
  return documentTargetStore(txn).delete(sentinelKey$1(docKey));
9762
10136
  });
9763
10137
  }
@@ -9970,27 +10344,19 @@ class ObjectMap {
9970
10344
  */
9971
10345
  class RemoteDocumentChangeBuffer {
9972
10346
  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).
10347
+ // A mapping of document key to the new cache entry that should be written.
9975
10348
  this.changes = new ObjectMap(key => key.toString(), (l, r) => l.isEqual(r));
9976
10349
  this.changesApplied = false;
9977
10350
  }
9978
- getReadTime(key) {
9979
- const change = this.changes.get(key);
9980
- if (change) {
9981
- return change.readTime;
9982
- }
9983
- return SnapshotVersion.min();
9984
- }
9985
10351
  /**
9986
10352
  * Buffers a `RemoteDocumentCache.addEntry()` call.
9987
10353
  *
9988
10354
  * You can only modify documents that have already been retrieved via
9989
10355
  * `getEntry()/getEntries()` (enforced via IndexedDbs `apply()`).
9990
10356
  */
9991
- addEntry(document, readTime) {
10357
+ addEntry(document) {
9992
10358
  this.assertNotApplied();
9993
- this.changes.set(document.key, { document, readTime });
10359
+ this.changes.set(document.key, document);
9994
10360
  }
9995
10361
  /**
9996
10362
  * Buffers a `RemoteDocumentCache.removeEntry()` call.
@@ -9998,12 +10364,9 @@ class RemoteDocumentChangeBuffer {
9998
10364
  * You can only remove documents that have already been retrieved via
9999
10365
  * `getEntry()/getEntries()` (enforced via IndexedDbs `apply()`).
10000
10366
  */
10001
- removeEntry(key, readTime = null) {
10367
+ removeEntry(key, readTime) {
10002
10368
  this.assertNotApplied();
10003
- this.changes.set(key, {
10004
- document: MutableDocument.newInvalidDocument(key),
10005
- readTime
10006
- });
10369
+ this.changes.set(key, MutableDocument.newInvalidDocument(key).setReadTime(readTime));
10007
10370
  }
10008
10371
  /**
10009
10372
  * Looks up an entry in the cache. The buffered changes will first be checked,
@@ -10020,7 +10383,7 @@ class RemoteDocumentChangeBuffer {
10020
10383
  this.assertNotApplied();
10021
10384
  const bufferedEntry = this.changes.get(documentKey);
10022
10385
  if (bufferedEntry !== undefined) {
10023
- return PersistencePromise.resolve(bufferedEntry.document);
10386
+ return PersistencePromise.resolve(bufferedEntry);
10024
10387
  }
10025
10388
  else {
10026
10389
  return this.getFromCache(transaction, documentKey);
@@ -10231,7 +10594,7 @@ class IndexedDbRemoteDocumentCacheImpl {
10231
10594
  if (key.length !== immediateChildrenPathLength) {
10232
10595
  return;
10233
10596
  }
10234
- const document = fromDbRemoteDocument(this.serializer, dbRemoteDoc);
10597
+ const document = this.maybeDecodeDocument(DocumentKey.fromSegments(key), dbRemoteDoc);
10235
10598
  if (!query.path.isPrefixOf(document.key.path)) {
10236
10599
  control.done();
10237
10600
  }
@@ -10259,8 +10622,8 @@ class IndexedDbRemoteDocumentCacheImpl {
10259
10622
  return documentGlobalStore(txn).put(DbRemoteDocumentGlobal.key, metadata);
10260
10623
  }
10261
10624
  /**
10262
- * Decodes `remoteDoc` and returns the document (or null, if the document
10263
- * corresponds to the format used for sentinel deletes).
10625
+ * Decodes `dbRemoteDoc` and returns the document (or an invalid document if
10626
+ * the document corresponds to the format used for sentinel deletes).
10264
10627
  */
10265
10628
  maybeDecodeDocument(documentKey, dbRemoteDoc) {
10266
10629
  if (dbRemoteDoc) {
@@ -10354,8 +10717,8 @@ class IndexedDbRemoteDocumentChangeBuffer extends RemoteDocumentChangeBuffer {
10354
10717
  let collectionParents = new SortedSet((l, r) => primitiveComparator(l.canonicalString(), r.canonicalString()));
10355
10718
  this.changes.forEach((key, documentChange) => {
10356
10719
  const previousSize = this.documentSizes.get(key);
10357
- if (documentChange.document.isValidDocument()) {
10358
- const doc = toDbRemoteDocument(this.documentCache.serializer, documentChange.document, this.getReadTime(key));
10720
+ if (documentChange.isValidDocument()) {
10721
+ const doc = toDbRemoteDocument(this.documentCache.serializer, documentChange);
10359
10722
  collectionParents = collectionParents.add(key.path.popLast());
10360
10723
  const size = dbDocumentSize(doc);
10361
10724
  sizeDelta += size - previousSize;
@@ -10368,7 +10731,7 @@ class IndexedDbRemoteDocumentChangeBuffer extends RemoteDocumentChangeBuffer {
10368
10731
  // RemoteDocumentCache. This entry is represented by a NoDocument
10369
10732
  // with a version of 0 and ignored by `maybeDecodeDocument()` but
10370
10733
  // preserved in `getNewDocumentChanges()`.
10371
- const deletedDoc = toDbRemoteDocument(this.documentCache.serializer, MutableDocument.newNoDocument(key, SnapshotVersion.min()), this.getReadTime(key));
10734
+ const deletedDoc = toDbRemoteDocument(this.documentCache.serializer, documentChange.convertToNoDocument(SnapshotVersion.min()));
10372
10735
  promises.push(this.documentCache.addEntry(transaction, key, deletedDoc));
10373
10736
  }
10374
10737
  else {
@@ -10449,9 +10812,6 @@ class SchemaConverter {
10449
10812
  * and local feature development.
10450
10813
  */
10451
10814
  createOrUpgrade(db, txn, fromVersion, toVersion) {
10452
- hardAssert(fromVersion < toVersion &&
10453
- fromVersion >= 0 &&
10454
- toVersion <= SCHEMA_VERSION);
10455
10815
  const simpleDbTransaction = new SimpleDbTransaction('createOrUpgrade', txn);
10456
10816
  if (fromVersion < 1 && toVersion >= 1) {
10457
10817
  createPrimaryClientStore(db);
@@ -10518,6 +10878,11 @@ class SchemaConverter {
10518
10878
  createNamedQueriesStore(db);
10519
10879
  });
10520
10880
  }
10881
+ if (fromVersion < 12 && toVersion >= 12) {
10882
+ p = p.next(() => {
10883
+ createFieldIndex(db);
10884
+ });
10885
+ }
10521
10886
  return p;
10522
10887
  }
10523
10888
  addDocumentGlobal(txn) {
@@ -10724,6 +11089,17 @@ function createNamedQueriesStore(db) {
10724
11089
  db.createObjectStore(DbNamedQuery.store, {
10725
11090
  keyPath: DbNamedQuery.keyPath
10726
11091
  });
11092
+ }
11093
+ function createFieldIndex(db) {
11094
+ db.createObjectStore(DbIndexConfiguration.store, {
11095
+ keyPath: DbIndexConfiguration.keyPath
11096
+ });
11097
+ db.createObjectStore(DbIndexState.store, {
11098
+ keyPath: DbIndexState.keyPath
11099
+ });
11100
+ db.createObjectStore(DbIndexEntries.store, {
11101
+ keyPath: DbIndexEntries.keyPath
11102
+ });
10727
11103
  }
10728
11104
 
10729
11105
  /**
@@ -11955,14 +12331,14 @@ function localStoreApplyRemoteEventToLocalCache(localStore, remoteEvent) {
11955
12331
  }
11956
12332
  });
11957
12333
  let changedDocs = mutableDocumentMap();
11958
- remoteEvent.documentUpdates.forEach((key, doc) => {
12334
+ remoteEvent.documentUpdates.forEach(key => {
11959
12335
  if (remoteEvent.resolvedLimboDocuments.has(key)) {
11960
12336
  promises.push(localStoreImpl.persistence.referenceDelegate.updateLimboDocument(txn, key));
11961
12337
  }
11962
12338
  });
11963
12339
  // Each loop iteration only affects its "own" doc, so it's safe to get all the remote
11964
12340
  // documents in advance in a single call.
11965
- promises.push(populateDocumentChangeBuffer(txn, documentBuffer, remoteEvent.documentUpdates, remoteVersion, undefined).next(result => {
12341
+ promises.push(populateDocumentChangeBuffer(txn, documentBuffer, remoteEvent.documentUpdates).next(result => {
11966
12342
  changedDocs = result;
11967
12343
  }));
11968
12344
  // HACK: The only reason we allow a null snapshot version is so that we
@@ -12003,17 +12379,13 @@ function localStoreApplyRemoteEventToLocalCache(localStore, remoteEvent) {
12003
12379
  * Note: this function will use `documentVersions` if it is defined;
12004
12380
  * when it is not defined, resorts to `globalVersion`.
12005
12381
  */
12006
- function populateDocumentChangeBuffer(txn, documentBuffer, documents, globalVersion,
12007
- // TODO(wuandy): We could add `readTime` to MaybeDocument instead to remove
12008
- // this parameter.
12009
- documentVersions) {
12382
+ function populateDocumentChangeBuffer(txn, documentBuffer, documents) {
12010
12383
  let updatedKeys = documentKeySet();
12011
12384
  documents.forEach(k => (updatedKeys = updatedKeys.add(k)));
12012
12385
  return documentBuffer.getEntries(txn, updatedKeys).next(existingDocs => {
12013
12386
  let changedDocs = mutableDocumentMap();
12014
12387
  documents.forEach((key, doc) => {
12015
12388
  const existingDoc = existingDocs.get(key);
12016
- const docReadTime = (documentVersions === null || documentVersions === void 0 ? void 0 : documentVersions.get(key)) || globalVersion;
12017
12389
  // Note: The order of the steps below is important, since we want
12018
12390
  // to ensure that rejected limbo resolutions (which fabricate
12019
12391
  // NoDocuments with SnapshotVersion.min()) never add documents to
@@ -12022,14 +12394,14 @@ documentVersions) {
12022
12394
  // NoDocuments with SnapshotVersion.min() are used in manufactured
12023
12395
  // events. We remove these documents from cache since we lost
12024
12396
  // access.
12025
- documentBuffer.removeEntry(key, docReadTime);
12397
+ documentBuffer.removeEntry(key, doc.readTime);
12026
12398
  changedDocs = changedDocs.insert(key, doc);
12027
12399
  }
12028
12400
  else if (!existingDoc.isValidDocument() ||
12029
12401
  doc.version.compareTo(existingDoc.version) > 0 ||
12030
12402
  (doc.version.compareTo(existingDoc.version) === 0 &&
12031
12403
  existingDoc.hasPendingWrites)) {
12032
- documentBuffer.addEntry(doc, docReadTime);
12404
+ documentBuffer.addEntry(doc);
12033
12405
  changedDocs = changedDocs.insert(key, doc);
12034
12406
  }
12035
12407
  else {
@@ -12283,7 +12655,8 @@ function applyWriteToRemoteDocuments(localStoreImpl, txn, batchResult, documentB
12283
12655
  // We use the commitVersion as the readTime rather than the
12284
12656
  // document's updateTime since the updateTime is not advanced
12285
12657
  // for updates that do not modify the underlying document.
12286
- documentBuffer.addEntry(doc, batchResult.commitVersion);
12658
+ doc.setReadTime(batchResult.commitVersion);
12659
+ documentBuffer.addEntry(doc);
12287
12660
  }
12288
12661
  }
12289
12662
  });
@@ -12384,14 +12757,14 @@ async function localStoreApplyBundledDocuments(localStore, bundleConverter, docu
12384
12757
  const localStoreImpl = debugCast(localStore);
12385
12758
  let documentKeys = documentKeySet();
12386
12759
  let documentMap = mutableDocumentMap();
12387
- let versionMap = documentVersionMap();
12388
12760
  for (const bundleDoc of documents) {
12389
12761
  const documentKey = bundleConverter.toDocumentKey(bundleDoc.metadata.name);
12390
12762
  if (bundleDoc.document) {
12391
12763
  documentKeys = documentKeys.add(documentKey);
12392
12764
  }
12393
- documentMap = documentMap.insert(documentKey, bundleConverter.toMutableDocument(bundleDoc));
12394
- versionMap = versionMap.insert(documentKey, bundleConverter.toSnapshotVersion(bundleDoc.metadata.readTime));
12765
+ const doc = bundleConverter.toMutableDocument(bundleDoc);
12766
+ doc.setReadTime(bundleConverter.toSnapshotVersion(bundleDoc.metadata.readTime));
12767
+ documentMap = documentMap.insert(documentKey, doc);
12395
12768
  }
12396
12769
  const documentBuffer = localStoreImpl.remoteDocuments.newChangeBuffer({
12397
12770
  trackRemovals: true // Make sure document removals show up in `getNewDocumentChanges()`
@@ -12400,7 +12773,7 @@ async function localStoreApplyBundledDocuments(localStore, bundleConverter, docu
12400
12773
  // they will not get garbage collected right away.
12401
12774
  const umbrellaTargetData = await localStoreAllocateTarget(localStoreImpl, umbrellaTarget(bundleName));
12402
12775
  return localStoreImpl.persistence.runTransaction('Apply bundle documents', 'readwrite', txn => {
12403
- return populateDocumentChangeBuffer(txn, documentBuffer, documentMap, SnapshotVersion.min(), versionMap)
12776
+ return populateDocumentChangeBuffer(txn, documentBuffer, documentMap)
12404
12777
  .next(changedDocs => {
12405
12778
  documentBuffer.apply(txn);
12406
12779
  return changedDocs;
@@ -12881,15 +13254,14 @@ class MemoryRemoteDocumentCacheImpl {
12881
13254
  * All calls of `addEntry` are required to go through the RemoteDocumentChangeBuffer
12882
13255
  * returned by `newChangeBuffer()`.
12883
13256
  */
12884
- addEntry(transaction, doc, readTime) {
13257
+ addEntry(transaction, doc) {
12885
13258
  const key = doc.key;
12886
13259
  const entry = this.docs.get(key);
12887
13260
  const previousSize = entry ? entry.size : 0;
12888
13261
  const currentSize = this.sizer(doc);
12889
13262
  this.docs = this.docs.insert(key, {
12890
13263
  document: doc.mutableCopy(),
12891
- size: currentSize,
12892
- readTime
13264
+ size: currentSize
12893
13265
  });
12894
13266
  this.size += currentSize - previousSize;
12895
13267
  return this.indexManager.addToCollectionParentIndex(transaction, key.path.popLast());
@@ -12930,11 +13302,11 @@ class MemoryRemoteDocumentCacheImpl {
12930
13302
  const prefix = new DocumentKey(query.path.child(''));
12931
13303
  const iterator = this.docs.getIteratorFrom(prefix);
12932
13304
  while (iterator.hasNext()) {
12933
- const { key, value: { document, readTime } } = iterator.getNext();
13305
+ const { key, value: { document } } = iterator.getNext();
12934
13306
  if (!query.path.isPrefixOf(key.path)) {
12935
13307
  break;
12936
13308
  }
12937
- if (readTime.compareTo(sinceReadTime) <= 0) {
13309
+ if (document.readTime.compareTo(sinceReadTime) <= 0) {
12938
13310
  continue;
12939
13311
  }
12940
13312
  if (!queryMatches(query, document)) {
@@ -12978,8 +13350,8 @@ class MemoryRemoteDocumentChangeBuffer extends RemoteDocumentChangeBuffer {
12978
13350
  applyChanges(transaction) {
12979
13351
  const promises = [];
12980
13352
  this.changes.forEach((key, doc) => {
12981
- if (doc.document.isValidDocument()) {
12982
- promises.push(this.documentCache.addEntry(transaction, doc.document, this.getReadTime(key)));
13353
+ if (doc.isValidDocument()) {
13354
+ promises.push(this.documentCache.addEntry(transaction, doc));
12983
13355
  }
12984
13356
  else {
12985
13357
  this.documentCache.removeEntry(key);
@@ -13292,7 +13664,7 @@ class MemoryEagerDelegate {
13292
13664
  const key = DocumentKey.fromPath(path);
13293
13665
  return this.isReferenced(txn, key).next(isReferenced => {
13294
13666
  if (!isReferenced) {
13295
- changeBuffer.removeEntry(key);
13667
+ changeBuffer.removeEntry(key, SnapshotVersion.min());
13296
13668
  }
13297
13669
  });
13298
13670
  }).next(() => {
@@ -20156,12 +20528,12 @@ async function syncEngineListen(syncEngine, query) {
20156
20528
  }
20157
20529
  else {
20158
20530
  const targetData = await localStoreAllocateTarget(syncEngineImpl.localStore, queryToTarget(query));
20159
- const status = syncEngineImpl.sharedClientState.addLocalQueryTarget(targetData.targetId);
20160
- targetId = targetData.targetId;
20161
- viewSnapshot = await initializeViewAndComputeSnapshot(syncEngineImpl, query, targetId, status === 'current');
20162
20531
  if (syncEngineImpl.isPrimaryClient) {
20163
20532
  remoteStoreListen(syncEngineImpl.remoteStore, targetData);
20164
20533
  }
20534
+ const status = syncEngineImpl.sharedClientState.addLocalQueryTarget(targetData.targetId);
20535
+ targetId = targetData.targetId;
20536
+ viewSnapshot = await initializeViewAndComputeSnapshot(syncEngineImpl, query, targetId, status === 'current');
20165
20537
  }
20166
20538
  return viewSnapshot;
20167
20539
  }
@@ -20349,6 +20721,9 @@ async function syncEngineRejectListen(syncEngine, targetId, err) {
20349
20721
  // store to purge a document. However, it would be tricky to keep all of
20350
20722
  // the local store's invariants with another method.
20351
20723
  let documentUpdates = new SortedMap(DocumentKey.comparator);
20724
+ // TODO(b/217189216): This limbo document should ideally have a read time,
20725
+ // so that it is picked up by any read-time based scans. The backend,
20726
+ // however, does not send a read time for target removals.
20352
20727
  documentUpdates = documentUpdates.insert(limboKey, MutableDocument.newNoDocument(limboKey, SnapshotVersion.min()));
20353
20728
  const resolvedLimboDocuments = documentKeySet().add(limboKey);
20354
20729
  const event = new RemoteEvent(SnapshotVersion.min(),
@@ -22293,72 +22668,6 @@ function createBundleReader(data, serializer) {
22293
22668
  return newBundleReader(toByteStreamReader(content), serializer);
22294
22669
  }
22295
22670
 
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
22671
  /**
22363
22672
  * @license
22364
22673
  * Copyright 2020 Google LLC
@@ -24732,8 +25041,7 @@ class DocumentSnapshot extends DocumentSnapshot$1 {
24732
25041
  this.metadata = metadata;
24733
25042
  }
24734
25043
  /**
24735
- * Property of the `DocumentSnapshot` that signals whether or not the data
24736
- * exists. True if the document exists.
25044
+ * Returns whether or not the data exists. True if the document exists.
24737
25045
  */
24738
25046
  exists() {
24739
25047
  return super.exists();
@@ -25107,51 +25415,53 @@ function limitToLast(limit) {
25107
25415
  return new QueryLimitConstraint('limitToLast', limit, "L" /* Last */);
25108
25416
  }
25109
25417
  class QueryStartAtConstraint extends QueryConstraint {
25110
- constructor(type, _docOrFields, _before) {
25418
+ constructor(type, _docOrFields, _inclusive) {
25111
25419
  super();
25112
25420
  this.type = type;
25113
25421
  this._docOrFields = _docOrFields;
25114
- this._before = _before;
25422
+ this._inclusive = _inclusive;
25115
25423
  }
25116
25424
  _apply(query) {
25117
- const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._before);
25425
+ const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._inclusive);
25118
25426
  return new Query(query.firestore, query.converter, queryWithStartAt(query._query, bound));
25119
25427
  }
25120
25428
  }
25121
25429
  function startAt(...docOrFields) {
25122
- return new QueryStartAtConstraint('startAt', docOrFields, /*before=*/ true);
25430
+ return new QueryStartAtConstraint('startAt', docOrFields,
25431
+ /*inclusive=*/ true);
25123
25432
  }
25124
25433
  function startAfter(...docOrFields) {
25125
25434
  return new QueryStartAtConstraint('startAfter', docOrFields,
25126
- /*before=*/ false);
25435
+ /*inclusive=*/ false);
25127
25436
  }
25128
25437
  class QueryEndAtConstraint extends QueryConstraint {
25129
- constructor(type, _docOrFields, _before) {
25438
+ constructor(type, _docOrFields, _inclusive) {
25130
25439
  super();
25131
25440
  this.type = type;
25132
25441
  this._docOrFields = _docOrFields;
25133
- this._before = _before;
25442
+ this._inclusive = _inclusive;
25134
25443
  }
25135
25444
  _apply(query) {
25136
- const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._before);
25445
+ const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._inclusive);
25137
25446
  return new Query(query.firestore, query.converter, queryWithEndAt(query._query, bound));
25138
25447
  }
25139
25448
  }
25140
25449
  function endBefore(...docOrFields) {
25141
- return new QueryEndAtConstraint('endBefore', docOrFields, /*before=*/ true);
25450
+ return new QueryEndAtConstraint('endBefore', docOrFields,
25451
+ /*inclusive=*/ false);
25142
25452
  }
25143
25453
  function endAt(...docOrFields) {
25144
- return new QueryEndAtConstraint('endAt', docOrFields, /*before=*/ false);
25454
+ return new QueryEndAtConstraint('endAt', docOrFields, /*inclusive=*/ true);
25145
25455
  }
25146
25456
  /** Helper function to create a bound from a document or fields */
25147
- function newQueryBoundFromDocOrFields(query, methodName, docOrFields, before) {
25457
+ function newQueryBoundFromDocOrFields(query, methodName, docOrFields, inclusive) {
25148
25458
  docOrFields[0] = util$1.getModularInstance(docOrFields[0]);
25149
25459
  if (docOrFields[0] instanceof DocumentSnapshot$1) {
25150
- return newQueryBoundFromDocument(query._query, query.firestore._databaseId, methodName, docOrFields[0]._document, before);
25460
+ return newQueryBoundFromDocument(query._query, query.firestore._databaseId, methodName, docOrFields[0]._document, inclusive);
25151
25461
  }
25152
25462
  else {
25153
25463
  const reader = newUserDataReader(query.firestore);
25154
- return newQueryBoundFromFields(query._query, query.firestore._databaseId, reader, methodName, docOrFields, before);
25464
+ return newQueryBoundFromFields(query._query, query.firestore._databaseId, reader, methodName, docOrFields, inclusive);
25155
25465
  }
25156
25466
  }
25157
25467
  function newQueryFilter(query, methodName, dataReader, databaseId, fieldPath, op, value) {
@@ -25209,7 +25519,7 @@ function newQueryOrderBy(query, fieldPath, direction) {
25209
25519
  * of the query or if any of the fields in the order by are an uncommitted
25210
25520
  * server timestamp.
25211
25521
  */
25212
- function newQueryBoundFromDocument(query, databaseId, methodName, doc, before) {
25522
+ function newQueryBoundFromDocument(query, databaseId, methodName, doc, inclusive) {
25213
25523
  if (!doc) {
25214
25524
  throw new FirestoreError(Code.NOT_FOUND, `Can't use a DocumentSnapshot that doesn't exist for ` +
25215
25525
  `${methodName}().`);
@@ -25246,12 +25556,12 @@ function newQueryBoundFromDocument(query, databaseId, methodName, doc, before) {
25246
25556
  }
25247
25557
  }
25248
25558
  }
25249
- return new Bound(components, before);
25559
+ return new Bound(components, inclusive);
25250
25560
  }
25251
25561
  /**
25252
25562
  * Converts a list of field values to a `Bound` for the given query.
25253
25563
  */
25254
- function newQueryBoundFromFields(query, databaseId, dataReader, methodName, values, before) {
25564
+ function newQueryBoundFromFields(query, databaseId, dataReader, methodName, values, inclusive) {
25255
25565
  // Use explicit order by's because it has to match the query the user made
25256
25566
  const orderBy = query.explicitOrderBy;
25257
25567
  if (values.length > orderBy.length) {
@@ -25288,7 +25598,7 @@ function newQueryBoundFromFields(query, databaseId, dataReader, methodName, valu
25288
25598
  components.push(wrapped);
25289
25599
  }
25290
25600
  }
25291
- return new Bound(components, before);
25601
+ return new Bound(components, inclusive);
25292
25602
  }
25293
25603
  /**
25294
25604
  * Parses the given `documentIdValue` into a `ReferenceValue`, throwing
@@ -26272,17 +26582,6 @@ function writeBatch(firestore) {
26272
26582
  ensureFirestoreConfigured(firestore);
26273
26583
  return new WriteBatch(firestore, mutations => executeWrite(firestore, mutations));
26274
26584
  }
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
26585
 
26287
26586
  /**
26288
26587
  * @license
@@ -26306,27 +26605,29 @@ function setIndexConfiguration(firestore, jsonOrConfiguration) {
26306
26605
  const indexConfiguration = typeof jsonOrConfiguration === 'string'
26307
26606
  ? tryParseJson(jsonOrConfiguration)
26308
26607
  : jsonOrConfiguration;
26608
+ const parsedIndexes = [];
26309
26609
  // PORTING NOTE: We don't return an error if the user has not enabled
26310
26610
  // persistence since `enableIndexeddbPersistence()` can fail on the Web.
26311
26611
  if (Array.isArray(indexConfiguration.indexes)) {
26312
26612
  for (const index of indexConfiguration.indexes) {
26313
- tryGetString(index, 'collectionGroup');
26613
+ const collectionGroup = tryGetString(index, 'collectionGroup');
26314
26614
  const segments = [];
26315
26615
  if (Array.isArray(index.fields)) {
26316
26616
  for (const field of index.fields) {
26317
26617
  const fieldPathString = tryGetString(field, 'fieldPath');
26318
26618
  const fieldPath = fieldPathFromDotSeparatedString('setIndexConfiguration', fieldPathString);
26319
26619
  if (field.arrayConfig === 'CONTAINS') {
26320
- segments.push(new Segment(fieldPath, 2 /* CONTAINS */));
26620
+ segments.push(new IndexSegment(fieldPath, 2 /* CONTAINS */));
26321
26621
  }
26322
26622
  else if (field.order === 'ASCENDING') {
26323
- segments.push(new Segment(fieldPath, 0 /* ASCENDING */));
26623
+ segments.push(new IndexSegment(fieldPath, 0 /* ASCENDING */));
26324
26624
  }
26325
26625
  else if (field.order === 'DESCENDING') {
26326
- segments.push(new Segment(fieldPath, 1 /* DESCENDING */));
26626
+ segments.push(new IndexSegment(fieldPath, 1 /* DESCENDING */));
26327
26627
  }
26328
26628
  }
26329
26629
  }
26630
+ parsedIndexes.push(new FieldIndex(FieldIndex.UNKNOWN_ID, collectionGroup, segments, IndexState.empty()));
26330
26631
  }
26331
26632
  }
26332
26633
  // TODO(indexing): Configure indexes