@firebase/firestore 3.4.4-canary.2dd99ae2d → 3.4.4-canary.50de44c2e

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 (128) hide show
  1. package/dist/firestore/src/api/snapshot.d.ts +1 -2
  2. package/dist/firestore/src/core/target.d.ts +8 -4
  3. package/dist/firestore/src/lite-api/query.d.ts +2 -2
  4. package/dist/firestore/src/local/index_manager.d.ts +52 -0
  5. package/dist/firestore/src/local/indexeddb_index_manager.d.ts +21 -2
  6. package/dist/firestore/src/local/indexeddb_persistence.d.ts +4 -4
  7. package/dist/firestore/src/local/indexeddb_remote_document_cache.d.ts +2 -8
  8. package/dist/firestore/src/local/indexeddb_schema.d.ts +149 -7
  9. package/dist/firestore/src/local/local_documents_view.d.ts +0 -1
  10. package/dist/firestore/src/local/local_serializer.d.ts +7 -2
  11. package/dist/firestore/src/local/memory_index_manager.d.ts +11 -0
  12. package/dist/firestore/src/local/memory_persistence.d.ts +3 -2
  13. package/dist/firestore/src/local/memory_remote_document_cache.d.ts +1 -3
  14. package/dist/firestore/src/local/persistence.d.ts +2 -2
  15. package/dist/firestore/src/local/remote_document_cache.d.ts +7 -9
  16. package/dist/firestore/src/local/simple_db.d.ts +1 -0
  17. package/dist/firestore/src/model/field_index.d.ts +2 -2
  18. package/dist/firestore/src/model/target_index_matcher.d.ts +70 -0
  19. package/dist/firestore/test/unit/local/counting_query_engine.d.ts +3 -3
  20. package/dist/firestore/test/unit/local/persistence_test_helpers.d.ts +1 -0
  21. package/dist/firestore/test/unit/local/test_index_manager.d.ts +11 -0
  22. package/dist/firestore/test/unit/local/test_remote_document_cache.d.ts +4 -2
  23. package/dist/firestore/test/unit/local/test_remote_document_change_buffer.d.ts +1 -1
  24. package/dist/firestore/test/unit/model/target_index_matcher.test.d.ts +17 -0
  25. package/dist/firestore/test/util/helpers.d.ts +1 -1
  26. package/dist/index.d.ts +1 -2
  27. package/dist/index.esm2017.js +3375 -3136
  28. package/dist/index.esm2017.js.map +1 -1
  29. package/dist/index.esm5.js +3649 -3430
  30. package/dist/index.esm5.js.map +1 -1
  31. package/dist/index.node.cjs.js +498 -219
  32. package/dist/index.node.cjs.js.map +1 -1
  33. package/dist/index.node.mjs +498 -219
  34. package/dist/index.node.mjs.map +1 -1
  35. package/dist/index.rn.js +3635 -3396
  36. package/dist/index.rn.js.map +1 -1
  37. package/dist/internal.d.ts +178 -14
  38. package/dist/lite/firestore/src/api/snapshot.d.ts +1 -2
  39. package/dist/lite/firestore/src/core/target.d.ts +8 -4
  40. package/dist/lite/firestore/src/lite-api/query.d.ts +2 -2
  41. package/dist/lite/firestore/src/local/index_manager.d.ts +52 -0
  42. package/dist/lite/firestore/src/local/indexeddb_index_manager.d.ts +21 -2
  43. package/dist/lite/firestore/src/local/indexeddb_persistence.d.ts +4 -4
  44. package/dist/lite/firestore/src/local/indexeddb_remote_document_cache.d.ts +2 -8
  45. package/dist/lite/firestore/src/local/indexeddb_schema.d.ts +149 -7
  46. package/dist/lite/firestore/src/local/local_documents_view.d.ts +0 -1
  47. package/dist/lite/firestore/src/local/local_serializer.d.ts +7 -2
  48. package/dist/lite/firestore/src/local/memory_index_manager.d.ts +11 -0
  49. package/dist/lite/firestore/src/local/memory_persistence.d.ts +3 -2
  50. package/dist/lite/firestore/src/local/memory_remote_document_cache.d.ts +1 -3
  51. package/dist/lite/firestore/src/local/persistence.d.ts +2 -2
  52. package/dist/lite/firestore/src/local/remote_document_cache.d.ts +7 -9
  53. package/dist/lite/firestore/src/local/simple_db.d.ts +1 -0
  54. package/dist/lite/firestore/src/model/field_index.d.ts +2 -2
  55. package/dist/lite/firestore/src/model/target_index_matcher.d.ts +70 -0
  56. package/dist/lite/firestore/test/unit/local/counting_query_engine.d.ts +3 -3
  57. package/dist/lite/firestore/test/unit/local/persistence_test_helpers.d.ts +1 -0
  58. package/dist/lite/firestore/test/unit/local/test_index_manager.d.ts +11 -0
  59. package/dist/lite/firestore/test/unit/local/test_remote_document_cache.d.ts +4 -2
  60. package/dist/lite/firestore/test/unit/local/test_remote_document_change_buffer.d.ts +1 -1
  61. package/dist/lite/firestore/test/unit/model/target_index_matcher.test.d.ts +17 -0
  62. package/dist/lite/firestore/test/util/helpers.d.ts +1 -1
  63. package/dist/lite/index.browser.esm2017.js +1146 -1143
  64. package/dist/lite/index.browser.esm2017.js.map +1 -1
  65. package/dist/lite/index.browser.esm5.js +332 -331
  66. package/dist/lite/index.browser.esm5.js.map +1 -1
  67. package/dist/lite/index.node.cjs.js +36 -29
  68. package/dist/lite/index.node.cjs.js.map +1 -1
  69. package/dist/lite/index.node.mjs +36 -29
  70. package/dist/lite/index.node.mjs.map +1 -1
  71. package/dist/lite/index.rn.esm2017.js +301 -298
  72. package/dist/lite/index.rn.esm2017.js.map +1 -1
  73. package/dist/lite/internal.d.ts +2 -2
  74. package/dist/lite/packages/firestore/dist/lite/index.browser.esm2017.d.ts +121 -121
  75. package/dist/lite/packages/firestore/src/api/snapshot.d.ts +1 -2
  76. package/dist/lite/packages/firestore/src/core/target.d.ts +8 -4
  77. package/dist/lite/packages/firestore/src/lite-api/query.d.ts +2 -2
  78. package/dist/lite/packages/firestore/src/local/index_manager.d.ts +52 -0
  79. package/dist/lite/packages/firestore/src/local/indexeddb_index_manager.d.ts +21 -2
  80. package/dist/lite/packages/firestore/src/local/indexeddb_persistence.d.ts +4 -4
  81. package/dist/lite/packages/firestore/src/local/indexeddb_remote_document_cache.d.ts +2 -8
  82. package/dist/lite/packages/firestore/src/local/indexeddb_schema.d.ts +149 -7
  83. package/dist/lite/packages/firestore/src/local/local_documents_view.d.ts +0 -1
  84. package/dist/lite/packages/firestore/src/local/local_serializer.d.ts +7 -2
  85. package/dist/lite/packages/firestore/src/local/memory_index_manager.d.ts +11 -0
  86. package/dist/lite/packages/firestore/src/local/memory_persistence.d.ts +3 -2
  87. package/dist/lite/packages/firestore/src/local/memory_remote_document_cache.d.ts +1 -3
  88. package/dist/lite/packages/firestore/src/local/persistence.d.ts +2 -2
  89. package/dist/lite/packages/firestore/src/local/remote_document_cache.d.ts +7 -9
  90. package/dist/lite/packages/firestore/src/local/simple_db.d.ts +1 -0
  91. package/dist/lite/packages/firestore/src/model/field_index.d.ts +2 -2
  92. package/dist/lite/packages/firestore/src/model/target_index_matcher.d.ts +70 -0
  93. package/dist/lite/packages/firestore/test/unit/local/counting_query_engine.d.ts +3 -3
  94. package/dist/lite/packages/firestore/test/unit/local/persistence_test_helpers.d.ts +1 -0
  95. package/dist/lite/packages/firestore/test/unit/local/test_index_manager.d.ts +11 -0
  96. package/dist/lite/packages/firestore/test/unit/local/test_remote_document_cache.d.ts +4 -2
  97. package/dist/lite/packages/firestore/test/unit/local/test_remote_document_change_buffer.d.ts +1 -1
  98. package/dist/lite/packages/firestore/test/unit/model/target_index_matcher.test.d.ts +17 -0
  99. package/dist/lite/packages/firestore/test/util/helpers.d.ts +1 -1
  100. package/dist/lite/private.d.ts +2 -2
  101. package/dist/packages/firestore/dist/index.esm2017.d.ts +177 -177
  102. package/dist/packages/firestore/src/api/snapshot.d.ts +1 -2
  103. package/dist/packages/firestore/src/core/target.d.ts +8 -4
  104. package/dist/packages/firestore/src/lite-api/query.d.ts +2 -2
  105. package/dist/packages/firestore/src/local/index_manager.d.ts +52 -0
  106. package/dist/packages/firestore/src/local/indexeddb_index_manager.d.ts +21 -2
  107. package/dist/packages/firestore/src/local/indexeddb_persistence.d.ts +4 -4
  108. package/dist/packages/firestore/src/local/indexeddb_remote_document_cache.d.ts +2 -8
  109. package/dist/packages/firestore/src/local/indexeddb_schema.d.ts +149 -7
  110. package/dist/packages/firestore/src/local/local_documents_view.d.ts +0 -1
  111. package/dist/packages/firestore/src/local/local_serializer.d.ts +7 -2
  112. package/dist/packages/firestore/src/local/memory_index_manager.d.ts +11 -0
  113. package/dist/packages/firestore/src/local/memory_persistence.d.ts +3 -2
  114. package/dist/packages/firestore/src/local/memory_remote_document_cache.d.ts +1 -3
  115. package/dist/packages/firestore/src/local/persistence.d.ts +2 -2
  116. package/dist/packages/firestore/src/local/remote_document_cache.d.ts +7 -9
  117. package/dist/packages/firestore/src/local/simple_db.d.ts +1 -0
  118. package/dist/packages/firestore/src/model/field_index.d.ts +2 -2
  119. package/dist/packages/firestore/src/model/target_index_matcher.d.ts +70 -0
  120. package/dist/packages/firestore/test/unit/local/counting_query_engine.d.ts +3 -3
  121. package/dist/packages/firestore/test/unit/local/persistence_test_helpers.d.ts +1 -0
  122. package/dist/packages/firestore/test/unit/local/test_index_manager.d.ts +11 -0
  123. package/dist/packages/firestore/test/unit/local/test_remote_document_cache.d.ts +4 -2
  124. package/dist/packages/firestore/test/unit/local/test_remote_document_change_buffer.d.ts +1 -1
  125. package/dist/packages/firestore/test/unit/model/target_index_matcher.test.d.ts +17 -0
  126. package/dist/packages/firestore/test/util/helpers.d.ts +1 -1
  127. package/dist/private.d.ts +178 -14
  128. 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.2dd99ae2d";
15
+ const version$1 = "3.4.4-canary.50de44c2e";
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.2dd99ae2d";
68
+ const version = "9.6.6-canary.50de44c2e";
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,116 @@ 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
+ /**
1782
+ * The index id for this entry. Undefined for indexes that are not yet
1783
+ * persisted.
1784
+ */
1785
+ indexId,
1786
+ /** The collection group this index belongs to. */
1787
+ collectionGroup,
1788
+ /** The fields to index for this index. */
1789
+ fields) {
1790
+ this.indexId = indexId;
1791
+ this.collectionGroup = collectionGroup;
1792
+ this.fields = fields;
1793
+ }
1794
+ }
1795
+ /** Name of the IndexedDb object store. */
1796
+ DbIndexConfiguration.store = 'indexConfiguration';
1797
+ DbIndexConfiguration.keyPath = 'indexId';
1798
+ /**
1799
+ * An index that provides access to the index configurations by collection
1800
+ * group.
1801
+ *
1802
+ * PORTING NOTE: iOS and Android maintain this index in-memory, but this is
1803
+ * not possible here as the Web client supports concurrent access to
1804
+ * persistence via multi-tab.
1805
+ */
1806
+ DbIndexConfiguration.collectionGroupIndex = 'collectionGroupIndex';
1807
+ DbIndexConfiguration.collectionGroupIndexPath = 'collectionGroup';
1808
+ /**
1809
+ * An object describing how up-to-date the index backfill is for each user and
1810
+ * index.
1811
+ */
1812
+ class DbIndexState {
1813
+ constructor(
1814
+ /** The index id for this entry. */
1815
+ indexId,
1816
+ /** The user id for this entry. */
1817
+ uid,
1818
+ /**
1819
+ * A number that indicates when the index was last updated (relative to
1820
+ * other indexes).
1821
+ */
1822
+ sequenceNumber,
1823
+ /**
1824
+ * The latest read time that has been indexed by Firestore for this field
1825
+ * index. Set to `{seconds: 0, nanos: 0}` if no documents have been indexed.
1826
+ */
1827
+ readTime,
1828
+ /**
1829
+ * The last document that has been indexed for this field index. Empty if
1830
+ * no documents have been indexed.
1831
+ */
1832
+ documentKey,
1833
+ /**
1834
+ * The largest mutation batch id that has been processed for this index. -1
1835
+ * if no mutations have been indexed.
1836
+ */
1837
+ largestBatchId) {
1838
+ this.indexId = indexId;
1839
+ this.uid = uid;
1840
+ this.sequenceNumber = sequenceNumber;
1841
+ this.readTime = readTime;
1842
+ this.documentKey = documentKey;
1843
+ this.largestBatchId = largestBatchId;
1844
+ }
1845
+ }
1846
+ /** Name of the IndexedDb object store. */
1847
+ DbIndexState.store = 'indexState';
1848
+ DbIndexState.keyPath = ['indexId', 'uid'];
1849
+ /**
1850
+ * An index that provides access to documents in a collection sorted by last
1851
+ * update time. Used by the backfiller.
1852
+ *
1853
+ * PORTING NOTE: iOS and Android maintain this index in-memory, but this is
1854
+ * not possible here as the Web client supports concurrent access to
1855
+ * persistence via multi-tab.
1856
+ */
1857
+ DbIndexState.sequenceNumberIndex = 'sequenceNumberIndex';
1858
+ DbIndexState.sequenceNumberIndexPath = ['uid', 'sequenceNumber'];
1859
+ /** An object that stores the encoded entries for all documents and fields. */
1860
+ class DbIndexEntry {
1861
+ constructor(
1862
+ /** The index id for this entry. */
1863
+ indexId,
1864
+ /** The user id for this entry. */
1865
+ uid,
1866
+ /** The encoded array index value for this entry. */
1867
+ arrayValue,
1868
+ /** The encoded directional value for equality and inequality filters. */
1869
+ directionalValue,
1870
+ /** The document key this entry points to. */
1871
+ documentKey) {
1872
+ this.indexId = indexId;
1873
+ this.uid = uid;
1874
+ this.arrayValue = arrayValue;
1875
+ this.directionalValue = directionalValue;
1876
+ this.documentKey = documentKey;
1877
+ }
1878
+ }
1879
+ /** Name of the IndexedDb object store. */
1880
+ DbIndexEntry.store = 'indexEntries';
1881
+ DbIndexEntry.keyPath = [
1882
+ 'indexId',
1883
+ 'uid',
1884
+ 'arrayValue',
1885
+ 'directionalValue',
1886
+ 'documentKey'
1887
+ ];
1798
1888
  // Visible for testing
1799
1889
  const V1_STORES = [
1800
1890
  DbMutationQueue.store,
@@ -1809,7 +1899,6 @@ const V1_STORES = [
1809
1899
  // V2 is no longer usable (see comment at top of file)
1810
1900
  // Visible for testing
1811
1901
  const V3_STORES = V1_STORES;
1812
- // Visible for testing
1813
1902
  // Note: DbRemoteDocumentChanges is no longer used and dropped with v9.
1814
1903
  const V4_STORES = [...V3_STORES, DbClientMetadata.store];
1815
1904
  // V5 does not change the set of stores.
@@ -1819,12 +1908,24 @@ const V8_STORES = [...V6_STORES, DbCollectionParent.store];
1819
1908
  // V9 does not change the set of stores.
1820
1909
  // V10 does not change the set of stores.
1821
1910
  const V11_STORES = [...V8_STORES, DbBundle.store, DbNamedQuery.store];
1822
- /**
1823
- * The list of all default IndexedDB stores used throughout the SDK. This is
1824
- * used when creating transactions so that access across all stores is done
1825
- * atomically.
1826
- */
1827
- const ALL_STORES = V11_STORES;
1911
+ const V12_STORES = [
1912
+ ...V11_STORES,
1913
+ DbIndexConfiguration.store,
1914
+ DbIndexState.store,
1915
+ DbIndexEntry.store
1916
+ ];
1917
+ /** Returns the object stores for the provided schema. */
1918
+ function getObjectStores(schemaVersion) {
1919
+ if (schemaVersion === 12) {
1920
+ return V12_STORES;
1921
+ }
1922
+ else if (schemaVersion === 11) {
1923
+ return V11_STORES;
1924
+ }
1925
+ else {
1926
+ fail();
1927
+ }
1928
+ }
1828
1929
 
1829
1930
  /**
1830
1931
  * @license
@@ -2121,6 +2222,15 @@ class SimpleDbTransaction {
2121
2222
  this.transaction.abort();
2122
2223
  }
2123
2224
  }
2225
+ maybeCommit() {
2226
+ // If the browser supports V3 IndexedDB, we invoke commit() explicitly to
2227
+ // speed up index DB processing if the event loop remains blocks.
2228
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2229
+ const maybeV3IndexedDb = this.transaction;
2230
+ if (!this.aborted && typeof maybeV3IndexedDb.commit === 'function') {
2231
+ maybeV3IndexedDb.commit();
2232
+ }
2233
+ }
2124
2234
  /**
2125
2235
  * Returns a SimpleDbStore<KeyType, ValueType> for the specified store. All
2126
2236
  * operations performed on the SimpleDbStore happen within the context of this
@@ -2317,6 +2427,10 @@ class SimpleDb {
2317
2427
  this.db = await this.ensureDb(action);
2318
2428
  const transaction = SimpleDbTransaction.open(this.db, action, readonly ? 'readonly' : 'readwrite', objectStores);
2319
2429
  const transactionFnResult = transactionFn(transaction)
2430
+ .next(result => {
2431
+ transaction.maybeCommit();
2432
+ return result;
2433
+ })
2320
2434
  .catch(error => {
2321
2435
  // Abort the transaction if there was an error.
2322
2436
  transaction.abort(error);
@@ -2489,13 +2603,29 @@ class SimpleDbStore {
2489
2603
  return wrapRequest(request);
2490
2604
  }
2491
2605
  loadAll(indexOrRange, range) {
2492
- const cursor = this.cursor(this.options(indexOrRange, range));
2493
- const results = [];
2494
- return this.iterateCursor(cursor, (key, value) => {
2495
- results.push(value);
2496
- }).next(() => {
2497
- return results;
2498
- });
2606
+ const iterateOptions = this.options(indexOrRange, range);
2607
+ // Use `getAll()` if the browser supports IndexedDB v3, as it is roughly
2608
+ // 20% faster. Unfortunately, getAll() does not support custom indices.
2609
+ if (!iterateOptions.index && typeof this.store.getAll === 'function') {
2610
+ const request = this.store.getAll(iterateOptions.range);
2611
+ return new PersistencePromise((resolve, reject) => {
2612
+ request.onerror = (event) => {
2613
+ reject(event.target.error);
2614
+ };
2615
+ request.onsuccess = (event) => {
2616
+ resolve(event.target.result);
2617
+ };
2618
+ });
2619
+ }
2620
+ else {
2621
+ const cursor = this.cursor(iterateOptions);
2622
+ const results = [];
2623
+ return this.iterateCursor(cursor, (key, value) => {
2624
+ results.push(value);
2625
+ }).next(() => {
2626
+ return results;
2627
+ });
2628
+ }
2499
2629
  }
2500
2630
  deleteAll(indexOrRange, range) {
2501
2631
  logDebug(LOG_TAG$g, 'DELETE ALL', this.store.name);
@@ -4349,12 +4479,12 @@ class FieldIndex {
4349
4479
  /** The collection ID this index applies to. */
4350
4480
  collectionGroup,
4351
4481
  /** The field segments for this index. */
4352
- segments,
4482
+ fields,
4353
4483
  /** Shows how up-to-date the index is for the current user. */
4354
4484
  indexState) {
4355
4485
  this.indexId = indexId;
4356
4486
  this.collectionGroup = collectionGroup;
4357
- this.segments = segments;
4487
+ this.fields = fields;
4358
4488
  this.indexState = indexState;
4359
4489
  }
4360
4490
  }
@@ -4464,27 +4594,29 @@ function newTarget(path, collectionGroup = null, orderBy = [], filters = [], lim
4464
4594
  function canonifyTarget(target) {
4465
4595
  const targetImpl = debugCast(target);
4466
4596
  if (targetImpl.memoizedCanonicalId === null) {
4467
- let canonicalId = targetImpl.path.canonicalString();
4597
+ let str = targetImpl.path.canonicalString();
4468
4598
  if (targetImpl.collectionGroup !== null) {
4469
- canonicalId += '|cg:' + targetImpl.collectionGroup;
4599
+ str += '|cg:' + targetImpl.collectionGroup;
4470
4600
  }
4471
- canonicalId += '|f:';
4472
- canonicalId += targetImpl.filters.map(f => canonifyFilter(f)).join(',');
4473
- canonicalId += '|ob:';
4474
- canonicalId += targetImpl.orderBy.map(o => canonifyOrderBy(o)).join(',');
4601
+ str += '|f:';
4602
+ str += targetImpl.filters.map(f => canonifyFilter(f)).join(',');
4603
+ str += '|ob:';
4604
+ str += targetImpl.orderBy.map(o => canonifyOrderBy(o)).join(',');
4475
4605
  if (!isNullOrUndefined(targetImpl.limit)) {
4476
- canonicalId += '|l:';
4477
- canonicalId += targetImpl.limit;
4606
+ str += '|l:';
4607
+ str += targetImpl.limit;
4478
4608
  }
4479
4609
  if (targetImpl.startAt) {
4480
- canonicalId += '|lb:';
4481
- canonicalId += canonifyBound(targetImpl.startAt);
4610
+ str += '|lb:';
4611
+ str += targetImpl.startAt.inclusive ? 'b:' : 'a:';
4612
+ str += targetImpl.startAt.position.map(p => canonicalId(p)).join(',');
4482
4613
  }
4483
4614
  if (targetImpl.endAt) {
4484
- canonicalId += '|ub:';
4485
- canonicalId += canonifyBound(targetImpl.endAt);
4615
+ str += '|ub:';
4616
+ str += targetImpl.endAt.inclusive ? 'a:' : 'b:';
4617
+ str += targetImpl.endAt.position.map(p => canonicalId(p)).join(',');
4486
4618
  }
4487
- targetImpl.memoizedCanonicalId = canonicalId;
4619
+ targetImpl.memoizedCanonicalId = str;
4488
4620
  }
4489
4621
  return targetImpl.memoizedCanonicalId;
4490
4622
  }
@@ -4507,10 +4639,14 @@ function stringifyTarget(target) {
4507
4639
  .join(', ')}]`;
4508
4640
  }
4509
4641
  if (target.startAt) {
4510
- str += ', startAt: ' + canonifyBound(target.startAt);
4642
+ str += ', startAt: ';
4643
+ str += target.startAt.inclusive ? 'b:' : 'a:';
4644
+ str += target.startAt.position.map(p => canonicalId(p)).join(',');
4511
4645
  }
4512
4646
  if (target.endAt) {
4513
- str += ', endAt: ' + canonifyBound(target.endAt);
4647
+ str += ', endAt: ';
4648
+ str += target.endAt.inclusive ? 'a:' : 'b:';
4649
+ str += target.endAt.position.map(p => canonicalId(p)).join(',');
4514
4650
  }
4515
4651
  return `Target(${str})`;
4516
4652
  }
@@ -4733,7 +4869,6 @@ class ArrayContainsAnyFilter extends FieldFilter {
4733
4869
  return other.arrayValue.values.some(val => arrayValueContains(this.value.arrayValue, val));
4734
4870
  }
4735
4871
  }
4736
- // TODO(indexing): Change Bound.before to "inclusive"
4737
4872
  /**
4738
4873
  * Represents a bound of a query.
4739
4874
  *
@@ -4749,17 +4884,11 @@ class ArrayContainsAnyFilter extends FieldFilter {
4749
4884
  * just after the provided values.
4750
4885
  */
4751
4886
  class Bound {
4752
- constructor(position, before) {
4887
+ constructor(position, inclusive) {
4753
4888
  this.position = position;
4754
- this.before = before;
4889
+ this.inclusive = inclusive;
4755
4890
  }
4756
4891
  }
4757
- function canonifyBound(bound) {
4758
- // TODO(b/29183165): Make this collision robust.
4759
- return `${bound.before ? 'b' : 'a'}:${bound.position
4760
- .map(p => canonicalId(p))
4761
- .join(',')}`;
4762
- }
4763
4892
  /**
4764
4893
  * An ordering on a field, in some Direction. Direction defaults to ASCENDING.
4765
4894
  */
@@ -4779,11 +4908,7 @@ function stringifyOrderBy(orderBy) {
4779
4908
  function orderByEquals(left, right) {
4780
4909
  return left.dir === right.dir && left.field.isEqual(right.field);
4781
4910
  }
4782
- /**
4783
- * Returns true if a document sorts before a bound using the provided sort
4784
- * order.
4785
- */
4786
- function sortsBeforeDocument(bound, orderBy, doc) {
4911
+ function boundCompareToDocument(bound, orderBy, doc) {
4787
4912
  let comparison = 0;
4788
4913
  for (let i = 0; i < bound.position.length; i++) {
4789
4914
  const orderByComponent = orderBy[i];
@@ -4802,7 +4927,23 @@ function sortsBeforeDocument(bound, orderBy, doc) {
4802
4927
  break;
4803
4928
  }
4804
4929
  }
4805
- return bound.before ? comparison <= 0 : comparison < 0;
4930
+ return comparison;
4931
+ }
4932
+ /**
4933
+ * Returns true if a document sorts after a bound using the provided sort
4934
+ * order.
4935
+ */
4936
+ function boundSortsAfterDocument(bound, orderBy, doc) {
4937
+ const comparison = boundCompareToDocument(bound, orderBy, doc);
4938
+ return bound.inclusive ? comparison >= 0 : comparison > 0;
4939
+ }
4940
+ /**
4941
+ * Returns true if a document sorts before a bound using the provided sort
4942
+ * order.
4943
+ */
4944
+ function boundSortsBeforeDocument(bound, orderBy, doc) {
4945
+ const comparison = boundCompareToDocument(bound, orderBy, doc);
4946
+ return bound.inclusive ? comparison <= 0 : comparison < 0;
4806
4947
  }
4807
4948
  function boundEquals(left, right) {
4808
4949
  if (left === null) {
@@ -4811,7 +4952,7 @@ function boundEquals(left, right) {
4811
4952
  else if (right === null) {
4812
4953
  return false;
4813
4954
  }
4814
- if (left.before !== right.before ||
4955
+ if (left.inclusive !== right.inclusive ||
4815
4956
  left.position.length !== right.position.length) {
4816
4957
  return false;
4817
4958
  }
@@ -5015,10 +5156,10 @@ function queryToTarget(query) {
5015
5156
  }
5016
5157
  // We need to swap the cursors to match the now-flipped query ordering.
5017
5158
  const startAt = queryImpl.endAt
5018
- ? new Bound(queryImpl.endAt.position, !queryImpl.endAt.before)
5159
+ ? new Bound(queryImpl.endAt.position, !queryImpl.endAt.inclusive)
5019
5160
  : null;
5020
5161
  const endAt = queryImpl.startAt
5021
- ? new Bound(queryImpl.startAt.position, !queryImpl.startAt.before)
5162
+ ? new Bound(queryImpl.startAt.position, !queryImpl.startAt.inclusive)
5022
5163
  : null;
5023
5164
  // Now return as a LimitType.First query.
5024
5165
  queryImpl.memoizedTarget = newTarget(queryImpl.path, queryImpl.collectionGroup, orderBys, queryImpl.filters, queryImpl.limit, startAt, endAt);
@@ -5106,11 +5247,11 @@ function queryMatchesFilters(query, doc) {
5106
5247
  /** Makes sure a document is within the bounds, if provided. */
5107
5248
  function queryMatchesBounds(query, doc) {
5108
5249
  if (query.startAt &&
5109
- !sortsBeforeDocument(query.startAt, queryOrderBy(query), doc)) {
5250
+ !boundSortsBeforeDocument(query.startAt, queryOrderBy(query), doc)) {
5110
5251
  return false;
5111
5252
  }
5112
5253
  if (query.endAt &&
5113
- sortsBeforeDocument(query.endAt, queryOrderBy(query), doc)) {
5254
+ !boundSortsAfterDocument(query.endAt, queryOrderBy(query), doc)) {
5114
5255
  return false;
5115
5256
  }
5116
5257
  return true;
@@ -7989,10 +8130,10 @@ function toQueryTarget(serializer, target) {
7989
8130
  result.structuredQuery.limit = limit;
7990
8131
  }
7991
8132
  if (target.startAt) {
7992
- result.structuredQuery.startAt = toCursor(target.startAt);
8133
+ result.structuredQuery.startAt = toStartAtCursor(target.startAt);
7993
8134
  }
7994
8135
  if (target.endAt) {
7995
- result.structuredQuery.endAt = toCursor(target.endAt);
8136
+ result.structuredQuery.endAt = toEndAtCursor(target.endAt);
7996
8137
  }
7997
8138
  return result;
7998
8139
  }
@@ -8025,11 +8166,11 @@ function convertQueryTargetToQuery(target) {
8025
8166
  }
8026
8167
  let startAt = null;
8027
8168
  if (query.startAt) {
8028
- startAt = fromCursor(query.startAt);
8169
+ startAt = fromStartAtCursor(query.startAt);
8029
8170
  }
8030
8171
  let endAt = null;
8031
8172
  if (query.endAt) {
8032
- endAt = fromCursor(query.endAt);
8173
+ endAt = fromEndAtCursor(query.endAt);
8033
8174
  }
8034
8175
  return newQuery(path, collectionGroup, orderBy, filterBy, limit, "F" /* First */, startAt, endAt);
8035
8176
  }
@@ -8120,16 +8261,27 @@ function toOrder(orderBys) {
8120
8261
  function fromOrder(orderBys) {
8121
8262
  return orderBys.map(order => fromPropertyOrder(order));
8122
8263
  }
8123
- function toCursor(cursor) {
8264
+ function toStartAtCursor(cursor) {
8124
8265
  return {
8125
- before: cursor.before,
8266
+ before: cursor.inclusive,
8126
8267
  values: cursor.position
8127
8268
  };
8128
8269
  }
8129
- function fromCursor(cursor) {
8130
- const before = !!cursor.before;
8270
+ function toEndAtCursor(cursor) {
8271
+ return {
8272
+ before: !cursor.inclusive,
8273
+ values: cursor.position
8274
+ };
8275
+ }
8276
+ function fromStartAtCursor(cursor) {
8277
+ const inclusive = !!cursor.before;
8278
+ const position = cursor.values || [];
8279
+ return new Bound(position, inclusive);
8280
+ }
8281
+ function fromEndAtCursor(cursor) {
8282
+ const inclusive = !cursor.before;
8131
8283
  const position = cursor.values || [];
8132
- return new Bound(position, before);
8284
+ return new Bound(position, inclusive);
8133
8285
  }
8134
8286
  // visible for testing
8135
8287
  function toDirection(dir) {
@@ -8593,6 +8745,19 @@ function fromBundleMetadata(metadata) {
8593
8745
  version: metadata.version,
8594
8746
  createTime: fromVersion(metadata.createTime)
8595
8747
  };
8748
+ }
8749
+ function toDbIndexConfiguration(index) {
8750
+ return new DbIndexConfiguration(index.indexId, index.collectionGroup, index.fields.map(s => [s.fieldPath.canonicalString(), s.kind]));
8751
+ }
8752
+ function fromDbIndexConfiguration(index, state) {
8753
+ const decodedState = state
8754
+ ? new IndexState(state.sequenceNumber, new IndexOffset(fromDbTimestamp(state.readTime), new DocumentKey(decodeResourcePath(state.documentKey)), state.largestBatchId))
8755
+ : IndexState.empty();
8756
+ const decodedSegments = index.fields.map(([fieldPath, kind]) => new IndexSegment(FieldPath$1.fromServerFormat(fieldPath), kind));
8757
+ return new FieldIndex(index.indexId, index.collectionGroup, decodedSegments, decodedState);
8758
+ }
8759
+ function toDbIndexState(indexId, user, sequenceNumber, offset) {
8760
+ return new DbIndexState(indexId, user.uid || '', sequenceNumber, toDbTimestamp(offset.readTime), encodeResourcePath(offset.documentKey.path), offset.largestBatchId);
8596
8761
  }
8597
8762
 
8598
8763
  /**
@@ -8682,6 +8847,38 @@ class MemoryIndexManager {
8682
8847
  getCollectionParents(transaction, collectionId) {
8683
8848
  return PersistencePromise.resolve(this.collectionParentIndex.getEntries(collectionId));
8684
8849
  }
8850
+ addFieldIndex(transaction, index) {
8851
+ // Field indices are not supported with memory persistence.
8852
+ return PersistencePromise.resolve();
8853
+ }
8854
+ deleteFieldIndex(transaction, index) {
8855
+ // Field indices are not supported with memory persistence.
8856
+ return PersistencePromise.resolve();
8857
+ }
8858
+ getDocumentsMatchingTarget(transaction, fieldIndex, target) {
8859
+ // Field indices are not supported with memory persistence.
8860
+ return PersistencePromise.resolve(documentKeySet());
8861
+ }
8862
+ getFieldIndex(transaction, target) {
8863
+ // Field indices are not supported with memory persistence.
8864
+ return PersistencePromise.resolve(null);
8865
+ }
8866
+ getFieldIndexes(transaction, collectionGroup) {
8867
+ // Field indices are not supported with memory persistence.
8868
+ return PersistencePromise.resolve([]);
8869
+ }
8870
+ getNextCollectionGroupToUpdate(transaction) {
8871
+ // Field indices are not supported with memory persistence.
8872
+ return PersistencePromise.resolve(null);
8873
+ }
8874
+ updateCollectionGroup(transaction, collectionGroup, offset) {
8875
+ // Field indices are not supported with memory persistence.
8876
+ return PersistencePromise.resolve();
8877
+ }
8878
+ updateIndexEntries(transaction, documents) {
8879
+ // Field indices are not supported with memory persistence.
8880
+ return PersistencePromise.resolve();
8881
+ }
8685
8882
  }
8686
8883
  /**
8687
8884
  * Internal implementation of the collection-parent index exposed by MemoryIndexManager.
@@ -8733,17 +8930,22 @@ class MemoryCollectionParentIndex {
8733
8930
  */
8734
8931
  /**
8735
8932
  * A persisted implementation of IndexManager.
8933
+ *
8934
+ * PORTING NOTE: Unlike iOS and Android, the Web SDK does not memoize index
8935
+ * data as it supports multi-tab access.
8736
8936
  */
8737
8937
  class IndexedDbIndexManager {
8738
- constructor() {
8938
+ constructor(user) {
8939
+ this.user = user;
8739
8940
  /**
8740
8941
  * An in-memory copy of the index entries we've already written since the SDK
8741
8942
  * launched. Used to avoid re-writing the same entry repeatedly.
8742
8943
  *
8743
- * This is *NOT* a complete cache of what's in persistence and so can never be used to
8744
- * satisfy reads.
8944
+ * This is *NOT* a complete cache of what's in persistence and so can never be
8945
+ * used to satisfy reads.
8745
8946
  */
8746
8947
  this.collectionParentsCache = new MemoryCollectionParentIndex();
8948
+ this.uid = user.uid || '';
8747
8949
  }
8748
8950
  /**
8749
8951
  * Adds a new entry to the collection parent index.
@@ -8790,6 +8992,85 @@ class IndexedDbIndexManager {
8790
8992
  return parentPaths;
8791
8993
  });
8792
8994
  }
8995
+ addFieldIndex(transaction, index) {
8996
+ // TODO(indexing): Verify that the auto-incrementing index ID works in
8997
+ // Safari & Firefox.
8998
+ const indexes = indexConfigurationStore(transaction);
8999
+ const dbIndex = toDbIndexConfiguration(index);
9000
+ delete dbIndex.indexId; // `indexId` is auto-populated by IndexedDb
9001
+ return indexes.add(dbIndex).next();
9002
+ }
9003
+ deleteFieldIndex(transaction, index) {
9004
+ const indexes = indexConfigurationStore(transaction);
9005
+ const states = indexStateStore(transaction);
9006
+ const entries = indexEntriesStore(transaction);
9007
+ return indexes
9008
+ .delete(index.indexId)
9009
+ .next(() => states.delete(IDBKeyRange.bound([index.indexId], [index.indexId + 1],
9010
+ /*lowerOpen=*/ false,
9011
+ /*upperOpen=*/ true)))
9012
+ .next(() => entries.delete(IDBKeyRange.bound([index.indexId], [index.indexId + 1],
9013
+ /*lowerOpen=*/ false,
9014
+ /*upperOpen=*/ true)));
9015
+ }
9016
+ getDocumentsMatchingTarget(transaction, fieldIndex, target) {
9017
+ // TODO(indexing): Implement
9018
+ return PersistencePromise.resolve(documentKeySet());
9019
+ }
9020
+ getFieldIndex(transaction, target) {
9021
+ // TODO(indexing): Implement
9022
+ return PersistencePromise.resolve(null);
9023
+ }
9024
+ getFieldIndexes(transaction, collectionGroup) {
9025
+ const indexes = indexConfigurationStore(transaction);
9026
+ const states = indexStateStore(transaction);
9027
+ return (collectionGroup
9028
+ ? indexes.loadAll(DbIndexConfiguration.collectionGroupIndex, IDBKeyRange.bound(collectionGroup, collectionGroup))
9029
+ : indexes.loadAll()).next(indexConfigs => {
9030
+ const result = [];
9031
+ return PersistencePromise.forEach(indexConfigs, (indexConfig) => {
9032
+ return states
9033
+ .get([indexConfig.indexId, this.uid])
9034
+ .next(indexState => {
9035
+ result.push(fromDbIndexConfiguration(indexConfig, indexState));
9036
+ });
9037
+ }).next(() => result);
9038
+ });
9039
+ }
9040
+ getNextCollectionGroupToUpdate(transaction) {
9041
+ return this.getFieldIndexes(transaction).next(indexes => {
9042
+ if (indexes.length === 0) {
9043
+ return null;
9044
+ }
9045
+ indexes.sort((l, r) => l.indexState.sequenceNumber - r.indexState.sequenceNumber);
9046
+ return indexes[0].collectionGroup;
9047
+ });
9048
+ }
9049
+ updateCollectionGroup(transaction, collectionGroup, offset) {
9050
+ const indexes = indexConfigurationStore(transaction);
9051
+ const states = indexStateStore(transaction);
9052
+ return this.getNextSequenceNumber(transaction).next(nextSequenceNumber => indexes
9053
+ .loadAll(DbIndexConfiguration.collectionGroupIndex, IDBKeyRange.bound(collectionGroup, collectionGroup))
9054
+ .next(configs => PersistencePromise.forEach(configs, (config) => states.put(toDbIndexState(config.indexId, this.user, nextSequenceNumber, offset)))));
9055
+ }
9056
+ updateIndexEntries(transaction, documents) {
9057
+ // TODO(indexing): Implement
9058
+ return PersistencePromise.resolve();
9059
+ }
9060
+ getNextSequenceNumber(transaction) {
9061
+ let nextSequenceNumber = 1;
9062
+ const states = indexStateStore(transaction);
9063
+ return states
9064
+ .iterate({
9065
+ index: DbIndexState.sequenceNumberIndex,
9066
+ reverse: true,
9067
+ range: IDBKeyRange.upperBound([this.uid, Number.MAX_SAFE_INTEGER])
9068
+ }, (_, state, controller) => {
9069
+ controller.done();
9070
+ nextSequenceNumber = state.sequenceNumber + 1;
9071
+ })
9072
+ .next(() => nextSequenceNumber);
9073
+ }
8793
9074
  }
8794
9075
  /**
8795
9076
  * Helper to get a typed SimpleDbStore for the collectionParents
@@ -8797,6 +9078,24 @@ class IndexedDbIndexManager {
8797
9078
  */
8798
9079
  function collectionParentsStore(txn) {
8799
9080
  return getStore(txn, DbCollectionParent.store);
9081
+ }
9082
+ /**
9083
+ * Helper to get a typed SimpleDbStore for the index entry object store.
9084
+ */
9085
+ function indexEntriesStore(txn) {
9086
+ return getStore(txn, DbIndexEntry.store);
9087
+ }
9088
+ /**
9089
+ * Helper to get a typed SimpleDbStore for the index configuration object store.
9090
+ */
9091
+ function indexConfigurationStore(txn) {
9092
+ return getStore(txn, DbIndexConfiguration.store);
9093
+ }
9094
+ /**
9095
+ * Helper to get a typed SimpleDbStore for the index state object store.
9096
+ */
9097
+ function indexStateStore(txn) {
9098
+ return getStore(txn, DbIndexState.store);
8800
9099
  }
8801
9100
 
8802
9101
  /**
@@ -10266,12 +10565,10 @@ class RemoteDocumentChangeBuffer {
10266
10565
  * `newIndexedDbRemoteDocumentCache()`.
10267
10566
  */
10268
10567
  class IndexedDbRemoteDocumentCacheImpl {
10269
- /**
10270
- * @param serializer - The document serializer.
10271
- * @param indexManager - The query indexes that need to be maintained.
10272
- */
10273
- constructor(serializer, indexManager) {
10568
+ constructor(serializer) {
10274
10569
  this.serializer = serializer;
10570
+ }
10571
+ setIndexManager(indexManager) {
10275
10572
  this.indexManager = indexManager;
10276
10573
  }
10277
10574
  /**
@@ -10393,21 +10690,21 @@ class IndexedDbRemoteDocumentCacheImpl {
10393
10690
  }
10394
10691
  });
10395
10692
  }
10396
- getDocumentsMatchingQuery(transaction, query, sinceReadTime) {
10693
+ getAll(transaction, collection, sinceReadTime) {
10397
10694
  let results = mutableDocumentMap();
10398
- const immediateChildrenPathLength = query.path.length + 1;
10695
+ const immediateChildrenPathLength = collection.length + 1;
10399
10696
  const iterationOptions = {};
10400
10697
  if (sinceReadTime.isEqual(SnapshotVersion.min())) {
10401
10698
  // Documents are ordered by key, so we can use a prefix scan to narrow
10402
10699
  // down the documents we need to match the query against.
10403
- const startKey = query.path.toArray();
10700
+ const startKey = collection.toArray();
10404
10701
  iterationOptions.range = IDBKeyRange.lowerBound(startKey);
10405
10702
  }
10406
10703
  else {
10407
10704
  // Execute an index-free query and filter by read time. This is safe
10408
10705
  // since all document changes to queries that have a
10409
10706
  // lastLimboFreeSnapshotVersion (`sinceReadTime`) have a read time set.
10410
- const collectionKey = query.path.toArray();
10707
+ const collectionKey = collection.toArray();
10411
10708
  const readTimeKey = toDbTimestampKey(sinceReadTime);
10412
10709
  iterationOptions.range = IDBKeyRange.lowerBound([collectionKey, readTimeKey],
10413
10710
  /* open= */ true);
@@ -10424,12 +10721,12 @@ class IndexedDbRemoteDocumentCacheImpl {
10424
10721
  return;
10425
10722
  }
10426
10723
  const document = this.maybeDecodeDocument(DocumentKey.fromSegments(key), dbRemoteDoc);
10427
- if (!query.path.isPrefixOf(document.key.path)) {
10428
- control.done();
10429
- }
10430
- else if (queryMatches(query, document)) {
10724
+ if (collection.isPrefixOf(document.key.path)) {
10431
10725
  results = results.insert(document.key, document);
10432
10726
  }
10727
+ else {
10728
+ control.done();
10729
+ }
10433
10730
  })
10434
10731
  .next(() => results);
10435
10732
  }
@@ -10467,14 +10764,9 @@ class IndexedDbRemoteDocumentCacheImpl {
10467
10764
  return MutableDocument.newInvalidDocument(documentKey);
10468
10765
  }
10469
10766
  }
10470
- /**
10471
- * Creates a new IndexedDbRemoteDocumentCache.
10472
- *
10473
- * @param serializer - The document serializer.
10474
- * @param indexManager - The query indexes that need to be maintained.
10475
- */
10476
- function newIndexedDbRemoteDocumentCache(serializer, indexManager) {
10477
- return new IndexedDbRemoteDocumentCacheImpl(serializer, indexManager);
10767
+ /** Creates a new IndexedDbRemoteDocumentCache. */
10768
+ function newIndexedDbRemoteDocumentCache(serializer) {
10769
+ return new IndexedDbRemoteDocumentCacheImpl(serializer);
10478
10770
  }
10479
10771
  /**
10480
10772
  * Returns the set of documents that have changed since the specified read
@@ -10641,9 +10933,6 @@ class SchemaConverter {
10641
10933
  * and local feature development.
10642
10934
  */
10643
10935
  createOrUpgrade(db, txn, fromVersion, toVersion) {
10644
- hardAssert(fromVersion < toVersion &&
10645
- fromVersion >= 0 &&
10646
- toVersion <= SCHEMA_VERSION);
10647
10936
  const simpleDbTransaction = new SimpleDbTransaction('createOrUpgrade', txn);
10648
10937
  if (fromVersion < 1 && toVersion >= 1) {
10649
10938
  createPrimaryClientStore(db);
@@ -10710,6 +10999,11 @@ class SchemaConverter {
10710
10999
  createNamedQueriesStore(db);
10711
11000
  });
10712
11001
  }
11002
+ if (fromVersion < 12 && toVersion >= 12) {
11003
+ p = p.next(() => {
11004
+ createFieldIndex(db);
11005
+ });
11006
+ }
10713
11007
  return p;
10714
11008
  }
10715
11009
  addDocumentGlobal(txn) {
@@ -10916,6 +11210,20 @@ function createNamedQueriesStore(db) {
10916
11210
  db.createObjectStore(DbNamedQuery.store, {
10917
11211
  keyPath: DbNamedQuery.keyPath
10918
11212
  });
11213
+ }
11214
+ function createFieldIndex(db) {
11215
+ const indexConfiguratioStore = db.createObjectStore(DbIndexConfiguration.store, {
11216
+ keyPath: DbIndexConfiguration.keyPath,
11217
+ autoIncrement: true
11218
+ });
11219
+ indexConfiguratioStore.createIndex(DbIndexConfiguration.collectionGroupIndex, DbIndexConfiguration.collectionGroupIndexPath, { unique: false });
11220
+ const indexStateStore = db.createObjectStore(DbIndexState.store, {
11221
+ keyPath: DbIndexState.keyPath
11222
+ });
11223
+ indexStateStore.createIndex(DbIndexState.sequenceNumberIndex, DbIndexState.sequenceNumberIndexPath, { unique: false });
11224
+ db.createObjectStore(DbIndexEntry.store, {
11225
+ keyPath: DbIndexEntry.keyPath
11226
+ });
10919
11227
  }
10920
11228
 
10921
11229
  /**
@@ -11027,7 +11335,7 @@ class IndexedDbPersistence {
11027
11335
  * If set to true, forcefully obtains database access. Existing tabs will
11028
11336
  * no longer be able to access IndexedDB.
11029
11337
  */
11030
- forceOwningTab) {
11338
+ forceOwningTab, schemaVersion = SCHEMA_VERSION) {
11031
11339
  this.allowTabSynchronization = allowTabSynchronization;
11032
11340
  this.persistenceKey = persistenceKey;
11033
11341
  this.clientId = clientId;
@@ -11036,6 +11344,7 @@ class IndexedDbPersistence {
11036
11344
  this.document = document;
11037
11345
  this.sequenceNumberSyncer = sequenceNumberSyncer;
11038
11346
  this.forceOwningTab = forceOwningTab;
11347
+ this.schemaVersion = schemaVersion;
11039
11348
  this.listenSequence = null;
11040
11349
  this._started = false;
11041
11350
  this.isPrimary = false;
@@ -11057,10 +11366,9 @@ class IndexedDbPersistence {
11057
11366
  this.referenceDelegate = new IndexedDbLruDelegateImpl(this, lruParams);
11058
11367
  this.dbName = persistenceKey + MAIN_DATABASE;
11059
11368
  this.serializer = new LocalSerializer(serializer);
11060
- this.simpleDb = new SimpleDb(this.dbName, SCHEMA_VERSION, new SchemaConverter(this.serializer));
11369
+ this.simpleDb = new SimpleDb(this.dbName, this.schemaVersion, new SchemaConverter(this.serializer));
11061
11370
  this.targetCache = new IndexedDbTargetCache(this.referenceDelegate, this.serializer);
11062
- this.indexManager = new IndexedDbIndexManager();
11063
- this.remoteDocumentCache = newIndexedDbRemoteDocumentCache(this.serializer, this.indexManager);
11371
+ this.remoteDocumentCache = newIndexedDbRemoteDocumentCache(this.serializer);
11064
11372
  this.bundleCache = new IndexedDbBundleCache();
11065
11373
  if (this.window && this.window.localStorage) {
11066
11374
  this.webStorage = this.window.localStorage;
@@ -11396,8 +11704,8 @@ class IndexedDbPersistence {
11396
11704
  get started() {
11397
11705
  return this._started;
11398
11706
  }
11399
- getMutationQueue(user) {
11400
- return IndexedDbMutationQueue.forUser(user, this.serializer, this.indexManager, this.referenceDelegate);
11707
+ getMutationQueue(user, indexManager) {
11708
+ return IndexedDbMutationQueue.forUser(user, this.serializer, indexManager, this.referenceDelegate);
11401
11709
  }
11402
11710
  getTargetCache() {
11403
11711
  return this.targetCache;
@@ -11405,8 +11713,8 @@ class IndexedDbPersistence {
11405
11713
  getRemoteDocumentCache() {
11406
11714
  return this.remoteDocumentCache;
11407
11715
  }
11408
- getIndexManager() {
11409
- return this.indexManager;
11716
+ getIndexManager(user) {
11717
+ return new IndexedDbIndexManager(user);
11410
11718
  }
11411
11719
  getBundleCache() {
11412
11720
  return this.bundleCache;
@@ -11414,11 +11722,12 @@ class IndexedDbPersistence {
11414
11722
  runTransaction(action, mode, transactionOperation) {
11415
11723
  logDebug(LOG_TAG$d, 'Starting transaction:', action);
11416
11724
  const simpleDbMode = mode === 'readonly' ? 'readonly' : 'readwrite';
11725
+ const objectStores = getObjectStores(this.schemaVersion);
11417
11726
  let persistenceTransaction;
11418
11727
  // Do all transactions as readwrite against all object stores, since we
11419
11728
  // are the only reader/writer.
11420
11729
  return this.simpleDb
11421
- .runTransaction(action, simpleDbMode, ALL_STORES, simpleDbTxn => {
11730
+ .runTransaction(action, simpleDbMode, objectStores, simpleDbTxn => {
11422
11731
  persistenceTransaction = new IndexedDbTransaction(simpleDbTxn, this.listenSequence
11423
11732
  ? this.listenSequence.next()
11424
11733
  : ListenSequence.INVALID);
@@ -11790,39 +12099,28 @@ class LocalDocumentsView {
11790
12099
  getDocumentsMatchingCollectionQuery(transaction, query, sinceReadTime) {
11791
12100
  // Query the remote documents and overlay mutations.
11792
12101
  let results;
11793
- let mutationBatches;
11794
12102
  return this.remoteDocumentCache
11795
- .getDocumentsMatchingQuery(transaction, query, sinceReadTime)
12103
+ .getAll(transaction, query.path, sinceReadTime)
11796
12104
  .next(queryResults => {
11797
12105
  results = queryResults;
11798
12106
  return this.mutationQueue.getAllMutationBatchesAffectingQuery(transaction, query);
11799
12107
  })
11800
- .next(matchingMutationBatches => {
11801
- mutationBatches = matchingMutationBatches;
11802
- // It is possible that a PatchMutation can make a document match a query, even if
11803
- // the version in the RemoteDocumentCache is not a match yet (waiting for server
11804
- // to ack). To handle this, we find all document keys affected by the PatchMutations
11805
- // that are not in `result` yet, and back fill them via `remoteDocumentCache.getEntries`,
11806
- // otherwise those `PatchMutations` will be ignored because no base document can be found,
11807
- // and lead to missing result for the query.
11808
- return this.addMissingBaseDocuments(transaction, mutationBatches, results).next(mergedDocuments => {
11809
- results = mergedDocuments;
11810
- for (const batch of mutationBatches) {
11811
- for (const mutation of batch.mutations) {
11812
- const key = mutation.key;
11813
- let document = results.get(key);
11814
- if (document == null) {
11815
- // Create invalid document to apply mutations on top of
11816
- document = MutableDocument.newInvalidDocument(key);
11817
- results = results.insert(key, document);
11818
- }
11819
- mutationApplyToLocalView(mutation, document, batch.localWriteTime);
11820
- if (!document.isFoundDocument()) {
11821
- results = results.remove(key);
11822
- }
12108
+ .next(mutationBatches => {
12109
+ for (const batch of mutationBatches) {
12110
+ for (const mutation of batch.mutations) {
12111
+ const key = mutation.key;
12112
+ let document = results.get(key);
12113
+ if (document == null) {
12114
+ // Create invalid document to apply mutations on top of
12115
+ document = MutableDocument.newInvalidDocument(key);
12116
+ results = results.insert(key, document);
12117
+ }
12118
+ mutationApplyToLocalView(mutation, document, batch.localWriteTime);
12119
+ if (!document.isFoundDocument()) {
12120
+ results = results.remove(key);
11823
12121
  }
11824
12122
  }
11825
- });
12123
+ }
11826
12124
  })
11827
12125
  .next(() => {
11828
12126
  // Finally, filter out any documents that don't actually match
@@ -11835,29 +12133,6 @@ class LocalDocumentsView {
11835
12133
  return results;
11836
12134
  });
11837
12135
  }
11838
- addMissingBaseDocuments(transaction, matchingMutationBatches, existingDocuments) {
11839
- let missingBaseDocEntriesForPatching = documentKeySet();
11840
- for (const batch of matchingMutationBatches) {
11841
- for (const mutation of batch.mutations) {
11842
- if (mutation instanceof PatchMutation &&
11843
- existingDocuments.get(mutation.key) === null) {
11844
- missingBaseDocEntriesForPatching =
11845
- missingBaseDocEntriesForPatching.add(mutation.key);
11846
- }
11847
- }
11848
- }
11849
- let mergedDocuments = existingDocuments;
11850
- return this.remoteDocumentCache
11851
- .getEntries(transaction, missingBaseDocEntriesForPatching)
11852
- .next(missingBaseDocs => {
11853
- missingBaseDocs.forEach((key, doc) => {
11854
- if (doc.isFoundDocument()) {
11855
- mergedDocuments = mergedDocuments.insert(key, doc);
11856
- }
11857
- });
11858
- return mergedDocuments;
11859
- });
11860
- }
11861
12136
  }
11862
12137
 
11863
12138
  /**
@@ -11916,11 +12191,18 @@ class LocalStoreImpl {
11916
12191
  * PORTING NOTE: This is only used for multi-tab synchronization.
11917
12192
  */
11918
12193
  this.lastDocumentChangeReadTime = SnapshotVersion.min();
11919
- this.mutationQueue = persistence.getMutationQueue(initialUser);
11920
12194
  this.remoteDocuments = persistence.getRemoteDocumentCache();
11921
12195
  this.targetCache = persistence.getTargetCache();
11922
- this.localDocuments = new LocalDocumentsView(this.remoteDocuments, this.mutationQueue, this.persistence.getIndexManager());
11923
12196
  this.bundleCache = persistence.getBundleCache();
12197
+ this.initializeUserComponents(initialUser);
12198
+ }
12199
+ initializeUserComponents(user) {
12200
+ // TODO(indexing): Add spec tests that test these components change after a
12201
+ // user change
12202
+ this.indexManager = this.persistence.getIndexManager(user);
12203
+ this.mutationQueue = this.persistence.getMutationQueue(user, this.indexManager);
12204
+ this.localDocuments = new LocalDocumentsView(this.remoteDocuments, this.mutationQueue, this.indexManager);
12205
+ this.remoteDocuments.setIndexManager(this.indexManager);
11924
12206
  this.queryEngine.setLocalDocumentsView(this.localDocuments);
11925
12207
  }
11926
12208
  collectGarbage(garbageCollector) {
@@ -11942,8 +12224,6 @@ persistence, queryEngine, initialUser, serializer) {
11942
12224
  // change.
11943
12225
  async function localStoreHandleUserChange(localStore, user) {
11944
12226
  const localStoreImpl = debugCast(localStore);
11945
- let newMutationQueue = localStoreImpl.mutationQueue;
11946
- let newLocalDocuments = localStoreImpl.localDocuments;
11947
12227
  const result = await localStoreImpl.persistence.runTransaction('Handle user change', 'readonly', txn => {
11948
12228
  // Swap out the mutation queue, grabbing the pending mutation batches
11949
12229
  // before and after.
@@ -11952,11 +12232,8 @@ async function localStoreHandleUserChange(localStore, user) {
11952
12232
  .getAllMutationBatches(txn)
11953
12233
  .next(promisedOldBatches => {
11954
12234
  oldBatches = promisedOldBatches;
11955
- newMutationQueue = localStoreImpl.persistence.getMutationQueue(user);
11956
- // Recreate our LocalDocumentsView using the new
11957
- // MutationQueue.
11958
- newLocalDocuments = new LocalDocumentsView(localStoreImpl.remoteDocuments, newMutationQueue, localStoreImpl.persistence.getIndexManager());
11959
- return newMutationQueue.getAllMutationBatches(txn);
12235
+ localStoreImpl.initializeUserComponents(user);
12236
+ return localStoreImpl.mutationQueue.getAllMutationBatches(txn);
11960
12237
  })
11961
12238
  .next(newBatches => {
11962
12239
  const removedBatchIds = [];
@@ -11977,7 +12254,7 @@ async function localStoreHandleUserChange(localStore, user) {
11977
12254
  }
11978
12255
  // Return the set of all (potentially) changed documents and the list
11979
12256
  // of mutation batch IDs that were affected by change.
11980
- return newLocalDocuments
12257
+ return localStoreImpl.localDocuments
11981
12258
  .getDocuments(txn, changedKeys)
11982
12259
  .next(affectedDocuments => {
11983
12260
  return {
@@ -11988,9 +12265,6 @@ async function localStoreHandleUserChange(localStore, user) {
11988
12265
  });
11989
12266
  });
11990
12267
  });
11991
- localStoreImpl.mutationQueue = newMutationQueue;
11992
- localStoreImpl.localDocuments = newLocalDocuments;
11993
- localStoreImpl.queryEngine.setLocalDocumentsView(localStoreImpl.localDocuments);
11994
12268
  return result;
11995
12269
  }
11996
12270
  /* Accepts locally generated Mutations and commit them to storage. */
@@ -13056,14 +13330,16 @@ class MemoryRemoteDocumentCacheImpl {
13056
13330
  * expected to just return 0 to avoid unnecessarily doing the work of
13057
13331
  * calculating the size.
13058
13332
  */
13059
- constructor(indexManager, sizer) {
13060
- this.indexManager = indexManager;
13333
+ constructor(sizer) {
13061
13334
  this.sizer = sizer;
13062
13335
  /** Underlying cache of documents and their read times. */
13063
13336
  this.docs = documentEntryMap();
13064
13337
  /** Size of all cached documents. */
13065
13338
  this.size = 0;
13066
13339
  }
13340
+ setIndexManager(indexManager) {
13341
+ this.indexManager = indexManager;
13342
+ }
13067
13343
  /**
13068
13344
  * Adds the supplied entry to the cache and updates the cache size as appropriate.
13069
13345
  *
@@ -13111,21 +13387,22 @@ class MemoryRemoteDocumentCacheImpl {
13111
13387
  });
13112
13388
  return PersistencePromise.resolve(results);
13113
13389
  }
13114
- getDocumentsMatchingQuery(transaction, query, sinceReadTime) {
13390
+ getAll(transaction, collectionPath, sinceReadTime) {
13115
13391
  let results = mutableDocumentMap();
13116
13392
  // Documents are ordered by key, so we can use a prefix scan to narrow down
13117
13393
  // the documents we need to match the query against.
13118
- const prefix = new DocumentKey(query.path.child(''));
13394
+ const prefix = new DocumentKey(collectionPath.child(''));
13119
13395
  const iterator = this.docs.getIteratorFrom(prefix);
13120
13396
  while (iterator.hasNext()) {
13121
13397
  const { key, value: { document } } = iterator.getNext();
13122
- if (!query.path.isPrefixOf(key.path)) {
13398
+ if (!collectionPath.isPrefixOf(key.path)) {
13123
13399
  break;
13124
13400
  }
13125
- if (document.readTime.compareTo(sinceReadTime) <= 0) {
13401
+ if (key.path.length > collectionPath.length + 1) {
13402
+ // Exclude entries from subcollections.
13126
13403
  continue;
13127
13404
  }
13128
- if (!queryMatches(query, document)) {
13405
+ if (document.readTime.compareTo(sinceReadTime) <= 0) {
13129
13406
  continue;
13130
13407
  }
13131
13408
  results = results.insert(document.key, document.mutableCopy());
@@ -13147,13 +13424,12 @@ class MemoryRemoteDocumentCacheImpl {
13147
13424
  /**
13148
13425
  * Creates a new memory-only RemoteDocumentCache.
13149
13426
  *
13150
- * @param indexManager - A class that manages collection group indices.
13151
13427
  * @param sizer - Used to assess the size of a document. For eager GC, this is
13152
13428
  * expected to just return 0 to avoid unnecessarily doing the work of
13153
13429
  * calculating the size.
13154
13430
  */
13155
- function newMemoryRemoteDocumentCache(indexManager, sizer) {
13156
- return new MemoryRemoteDocumentCacheImpl(indexManager, sizer);
13431
+ function newMemoryRemoteDocumentCache(sizer) {
13432
+ return new MemoryRemoteDocumentCacheImpl(sizer);
13157
13433
  }
13158
13434
  /**
13159
13435
  * Handles the details of adding and updating documents in the MemoryRemoteDocumentCache.
@@ -13354,7 +13630,7 @@ class MemoryPersistence {
13354
13630
  this.targetCache = new MemoryTargetCache(this);
13355
13631
  const sizer = (doc) => this.referenceDelegate.documentSize(doc);
13356
13632
  this.indexManager = new MemoryIndexManager();
13357
- this.remoteDocumentCache = newMemoryRemoteDocumentCache(this.indexManager, sizer);
13633
+ this.remoteDocumentCache = newMemoryRemoteDocumentCache(sizer);
13358
13634
  this.serializer = new LocalSerializer(serializer);
13359
13635
  this.bundleCache = new MemoryBundleCache(this.serializer);
13360
13636
  }
@@ -13375,13 +13651,15 @@ class MemoryPersistence {
13375
13651
  setNetworkEnabled() {
13376
13652
  // No op.
13377
13653
  }
13378
- getIndexManager() {
13654
+ getIndexManager(user) {
13655
+ // We do not currently support indices for memory persistence, so we can
13656
+ // return the same shared instance of the memory index manager.
13379
13657
  return this.indexManager;
13380
13658
  }
13381
- getMutationQueue(user) {
13659
+ getMutationQueue(user, indexManager) {
13382
13660
  let queue = this.mutationQueues[user.toKey()];
13383
13661
  if (!queue) {
13384
- queue = new MemoryMutationQueue(this.indexManager, this.referenceDelegate);
13662
+ queue = new MemoryMutationQueue(indexManager, this.referenceDelegate);
13385
13663
  this.mutationQueues[user.toKey()] = queue;
13386
13664
  }
13387
13665
  return queue;
@@ -20344,12 +20622,12 @@ async function syncEngineListen(syncEngine, query) {
20344
20622
  }
20345
20623
  else {
20346
20624
  const targetData = await localStoreAllocateTarget(syncEngineImpl.localStore, queryToTarget(query));
20347
- const status = syncEngineImpl.sharedClientState.addLocalQueryTarget(targetData.targetId);
20348
- targetId = targetData.targetId;
20349
- viewSnapshot = await initializeViewAndComputeSnapshot(syncEngineImpl, query, targetId, status === 'current');
20350
20625
  if (syncEngineImpl.isPrimaryClient) {
20351
20626
  remoteStoreListen(syncEngineImpl.remoteStore, targetData);
20352
20627
  }
20628
+ const status = syncEngineImpl.sharedClientState.addLocalQueryTarget(targetData.targetId);
20629
+ targetId = targetData.targetId;
20630
+ viewSnapshot = await initializeViewAndComputeSnapshot(syncEngineImpl, query, targetId, status === 'current');
20353
20631
  }
20354
20632
  return viewSnapshot;
20355
20633
  }
@@ -24857,8 +25135,7 @@ class DocumentSnapshot extends DocumentSnapshot$1 {
24857
25135
  this.metadata = metadata;
24858
25136
  }
24859
25137
  /**
24860
- * Property of the `DocumentSnapshot` that signals whether or not the data
24861
- * exists. True if the document exists.
25138
+ * Returns whether or not the data exists. True if the document exists.
24862
25139
  */
24863
25140
  exists() {
24864
25141
  return super.exists();
@@ -25232,51 +25509,53 @@ function limitToLast(limit) {
25232
25509
  return new QueryLimitConstraint('limitToLast', limit, "L" /* Last */);
25233
25510
  }
25234
25511
  class QueryStartAtConstraint extends QueryConstraint {
25235
- constructor(type, _docOrFields, _before) {
25512
+ constructor(type, _docOrFields, _inclusive) {
25236
25513
  super();
25237
25514
  this.type = type;
25238
25515
  this._docOrFields = _docOrFields;
25239
- this._before = _before;
25516
+ this._inclusive = _inclusive;
25240
25517
  }
25241
25518
  _apply(query) {
25242
- const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._before);
25519
+ const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._inclusive);
25243
25520
  return new Query(query.firestore, query.converter, queryWithStartAt(query._query, bound));
25244
25521
  }
25245
25522
  }
25246
25523
  function startAt(...docOrFields) {
25247
- return new QueryStartAtConstraint('startAt', docOrFields, /*before=*/ true);
25524
+ return new QueryStartAtConstraint('startAt', docOrFields,
25525
+ /*inclusive=*/ true);
25248
25526
  }
25249
25527
  function startAfter(...docOrFields) {
25250
25528
  return new QueryStartAtConstraint('startAfter', docOrFields,
25251
- /*before=*/ false);
25529
+ /*inclusive=*/ false);
25252
25530
  }
25253
25531
  class QueryEndAtConstraint extends QueryConstraint {
25254
- constructor(type, _docOrFields, _before) {
25532
+ constructor(type, _docOrFields, _inclusive) {
25255
25533
  super();
25256
25534
  this.type = type;
25257
25535
  this._docOrFields = _docOrFields;
25258
- this._before = _before;
25536
+ this._inclusive = _inclusive;
25259
25537
  }
25260
25538
  _apply(query) {
25261
- const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._before);
25539
+ const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._inclusive);
25262
25540
  return new Query(query.firestore, query.converter, queryWithEndAt(query._query, bound));
25263
25541
  }
25264
25542
  }
25265
25543
  function endBefore(...docOrFields) {
25266
- return new QueryEndAtConstraint('endBefore', docOrFields, /*before=*/ true);
25544
+ return new QueryEndAtConstraint('endBefore', docOrFields,
25545
+ /*inclusive=*/ false);
25267
25546
  }
25268
25547
  function endAt(...docOrFields) {
25269
- return new QueryEndAtConstraint('endAt', docOrFields, /*before=*/ false);
25548
+ return new QueryEndAtConstraint('endAt', docOrFields, /*inclusive=*/ true);
25270
25549
  }
25271
25550
  /** Helper function to create a bound from a document or fields */
25272
- function newQueryBoundFromDocOrFields(query, methodName, docOrFields, before) {
25551
+ function newQueryBoundFromDocOrFields(query, methodName, docOrFields, inclusive) {
25273
25552
  docOrFields[0] = util$1.getModularInstance(docOrFields[0]);
25274
25553
  if (docOrFields[0] instanceof DocumentSnapshot$1) {
25275
- return newQueryBoundFromDocument(query._query, query.firestore._databaseId, methodName, docOrFields[0]._document, before);
25554
+ return newQueryBoundFromDocument(query._query, query.firestore._databaseId, methodName, docOrFields[0]._document, inclusive);
25276
25555
  }
25277
25556
  else {
25278
25557
  const reader = newUserDataReader(query.firestore);
25279
- return newQueryBoundFromFields(query._query, query.firestore._databaseId, reader, methodName, docOrFields, before);
25558
+ return newQueryBoundFromFields(query._query, query.firestore._databaseId, reader, methodName, docOrFields, inclusive);
25280
25559
  }
25281
25560
  }
25282
25561
  function newQueryFilter(query, methodName, dataReader, databaseId, fieldPath, op, value) {
@@ -25334,7 +25613,7 @@ function newQueryOrderBy(query, fieldPath, direction) {
25334
25613
  * of the query or if any of the fields in the order by are an uncommitted
25335
25614
  * server timestamp.
25336
25615
  */
25337
- function newQueryBoundFromDocument(query, databaseId, methodName, doc, before) {
25616
+ function newQueryBoundFromDocument(query, databaseId, methodName, doc, inclusive) {
25338
25617
  if (!doc) {
25339
25618
  throw new FirestoreError(Code.NOT_FOUND, `Can't use a DocumentSnapshot that doesn't exist for ` +
25340
25619
  `${methodName}().`);
@@ -25371,12 +25650,12 @@ function newQueryBoundFromDocument(query, databaseId, methodName, doc, before) {
25371
25650
  }
25372
25651
  }
25373
25652
  }
25374
- return new Bound(components, before);
25653
+ return new Bound(components, inclusive);
25375
25654
  }
25376
25655
  /**
25377
25656
  * Converts a list of field values to a `Bound` for the given query.
25378
25657
  */
25379
- function newQueryBoundFromFields(query, databaseId, dataReader, methodName, values, before) {
25658
+ function newQueryBoundFromFields(query, databaseId, dataReader, methodName, values, inclusive) {
25380
25659
  // Use explicit order by's because it has to match the query the user made
25381
25660
  const orderBy = query.explicitOrderBy;
25382
25661
  if (values.length > orderBy.length) {
@@ -25413,7 +25692,7 @@ function newQueryBoundFromFields(query, databaseId, dataReader, methodName, valu
25413
25692
  components.push(wrapped);
25414
25693
  }
25415
25694
  }
25416
- return new Bound(components, before);
25695
+ return new Bound(components, inclusive);
25417
25696
  }
25418
25697
  /**
25419
25698
  * Parses the given `documentIdValue` into a `ReferenceValue`, throwing