@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
@@ -8,7 +8,7 @@ import { credentials, loadPackageDefinition, Metadata } from '@grpc/grpc-js';
8
8
  import { fromJSON } from '@grpc/proto-loader';
9
9
 
10
10
  const name = "@firebase/firestore";
11
- const version$1 = "3.4.4-canary.2dd99ae2d";
11
+ const version$1 = "3.4.4-canary.50de44c2e";
12
12
 
13
13
  /**
14
14
  * @license
@@ -61,7 +61,7 @@ User.GOOGLE_CREDENTIALS = new User('google-credentials-uid');
61
61
  User.FIRST_PARTY = new User('first-party-uid');
62
62
  User.MOCK_USER = new User('mock-user');
63
63
 
64
- const version = "9.6.5-canary.2dd99ae2d";
64
+ const version = "9.6.6-canary.50de44c2e";
65
65
 
66
66
  /**
67
67
  * @license
@@ -1192,23 +1192,6 @@ function decodeResourcePath(path) {
1192
1192
  }
1193
1193
  return new ResourcePath(segments);
1194
1194
  }
1195
-
1196
- /**
1197
- * @license
1198
- * Copyright 2017 Google LLC
1199
- *
1200
- * Licensed under the Apache License, Version 2.0 (the "License");
1201
- * you may not use this file except in compliance with the License.
1202
- * You may obtain a copy of the License at
1203
- *
1204
- * http://www.apache.org/licenses/LICENSE-2.0
1205
- *
1206
- * Unless required by applicable law or agreed to in writing, software
1207
- * distributed under the License is distributed on an "AS IS" BASIS,
1208
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1209
- * See the License for the specific language governing permissions and
1210
- * limitations under the License.
1211
- */
1212
1195
  /**
1213
1196
  * Schema Version for the Web client:
1214
1197
  * 1. Initial version including Mutation Queue, Query Cache, and Remote
@@ -1227,6 +1210,7 @@ function decodeResourcePath(path) {
1227
1210
  * an auto-incrementing ID. This is required for Index-Free queries.
1228
1211
  * 10. Rewrite the canonical IDs to the explicit Protobuf-based format.
1229
1212
  * 11. Add bundles and named_queries for bundle support.
1213
+ * 12. Add indexing support.
1230
1214
  */
1231
1215
  const SCHEMA_VERSION = 11;
1232
1216
  /**
@@ -1753,9 +1737,7 @@ class DbClientMetadata {
1753
1737
  DbClientMetadata.store = 'clientMetadata';
1754
1738
  /** Keys are automatically assigned via the clientId properties. */
1755
1739
  DbClientMetadata.keyPath = 'clientId';
1756
- /**
1757
- * A object representing a bundle loaded by the SDK.
1758
- */
1740
+ /** An object representing a bundle loaded by the SDK. */
1759
1741
  class DbBundle {
1760
1742
  constructor(
1761
1743
  /** The ID of the loaded bundle. */
@@ -1772,9 +1754,7 @@ class DbBundle {
1772
1754
  /** Name of the IndexedDb object store. */
1773
1755
  DbBundle.store = 'bundles';
1774
1756
  DbBundle.keyPath = 'bundleId';
1775
- /**
1776
- * A object representing a named query loaded by the SDK via a bundle.
1777
- */
1757
+ /** An object representing a named query loaded by the SDK via a bundle. */
1778
1758
  class DbNamedQuery {
1779
1759
  constructor(
1780
1760
  /** The name of the query. */
@@ -1791,6 +1771,116 @@ class DbNamedQuery {
1791
1771
  /** Name of the IndexedDb object store. */
1792
1772
  DbNamedQuery.store = 'namedQueries';
1793
1773
  DbNamedQuery.keyPath = 'name';
1774
+ /** An object representing the global configuration for a field index. */
1775
+ class DbIndexConfiguration {
1776
+ constructor(
1777
+ /**
1778
+ * The index id for this entry. Undefined for indexes that are not yet
1779
+ * persisted.
1780
+ */
1781
+ indexId,
1782
+ /** The collection group this index belongs to. */
1783
+ collectionGroup,
1784
+ /** The fields to index for this index. */
1785
+ fields) {
1786
+ this.indexId = indexId;
1787
+ this.collectionGroup = collectionGroup;
1788
+ this.fields = fields;
1789
+ }
1790
+ }
1791
+ /** Name of the IndexedDb object store. */
1792
+ DbIndexConfiguration.store = 'indexConfiguration';
1793
+ DbIndexConfiguration.keyPath = 'indexId';
1794
+ /**
1795
+ * An index that provides access to the index configurations by collection
1796
+ * group.
1797
+ *
1798
+ * PORTING NOTE: iOS and Android maintain this index in-memory, but this is
1799
+ * not possible here as the Web client supports concurrent access to
1800
+ * persistence via multi-tab.
1801
+ */
1802
+ DbIndexConfiguration.collectionGroupIndex = 'collectionGroupIndex';
1803
+ DbIndexConfiguration.collectionGroupIndexPath = 'collectionGroup';
1804
+ /**
1805
+ * An object describing how up-to-date the index backfill is for each user and
1806
+ * index.
1807
+ */
1808
+ class DbIndexState {
1809
+ constructor(
1810
+ /** The index id for this entry. */
1811
+ indexId,
1812
+ /** The user id for this entry. */
1813
+ uid,
1814
+ /**
1815
+ * A number that indicates when the index was last updated (relative to
1816
+ * other indexes).
1817
+ */
1818
+ sequenceNumber,
1819
+ /**
1820
+ * The latest read time that has been indexed by Firestore for this field
1821
+ * index. Set to `{seconds: 0, nanos: 0}` if no documents have been indexed.
1822
+ */
1823
+ readTime,
1824
+ /**
1825
+ * The last document that has been indexed for this field index. Empty if
1826
+ * no documents have been indexed.
1827
+ */
1828
+ documentKey,
1829
+ /**
1830
+ * The largest mutation batch id that has been processed for this index. -1
1831
+ * if no mutations have been indexed.
1832
+ */
1833
+ largestBatchId) {
1834
+ this.indexId = indexId;
1835
+ this.uid = uid;
1836
+ this.sequenceNumber = sequenceNumber;
1837
+ this.readTime = readTime;
1838
+ this.documentKey = documentKey;
1839
+ this.largestBatchId = largestBatchId;
1840
+ }
1841
+ }
1842
+ /** Name of the IndexedDb object store. */
1843
+ DbIndexState.store = 'indexState';
1844
+ DbIndexState.keyPath = ['indexId', 'uid'];
1845
+ /**
1846
+ * An index that provides access to documents in a collection sorted by last
1847
+ * update time. Used by the backfiller.
1848
+ *
1849
+ * PORTING NOTE: iOS and Android maintain this index in-memory, but this is
1850
+ * not possible here as the Web client supports concurrent access to
1851
+ * persistence via multi-tab.
1852
+ */
1853
+ DbIndexState.sequenceNumberIndex = 'sequenceNumberIndex';
1854
+ DbIndexState.sequenceNumberIndexPath = ['uid', 'sequenceNumber'];
1855
+ /** An object that stores the encoded entries for all documents and fields. */
1856
+ class DbIndexEntry {
1857
+ constructor(
1858
+ /** The index id for this entry. */
1859
+ indexId,
1860
+ /** The user id for this entry. */
1861
+ uid,
1862
+ /** The encoded array index value for this entry. */
1863
+ arrayValue,
1864
+ /** The encoded directional value for equality and inequality filters. */
1865
+ directionalValue,
1866
+ /** The document key this entry points to. */
1867
+ documentKey) {
1868
+ this.indexId = indexId;
1869
+ this.uid = uid;
1870
+ this.arrayValue = arrayValue;
1871
+ this.directionalValue = directionalValue;
1872
+ this.documentKey = documentKey;
1873
+ }
1874
+ }
1875
+ /** Name of the IndexedDb object store. */
1876
+ DbIndexEntry.store = 'indexEntries';
1877
+ DbIndexEntry.keyPath = [
1878
+ 'indexId',
1879
+ 'uid',
1880
+ 'arrayValue',
1881
+ 'directionalValue',
1882
+ 'documentKey'
1883
+ ];
1794
1884
  // Visible for testing
1795
1885
  const V1_STORES = [
1796
1886
  DbMutationQueue.store,
@@ -1805,7 +1895,6 @@ const V1_STORES = [
1805
1895
  // V2 is no longer usable (see comment at top of file)
1806
1896
  // Visible for testing
1807
1897
  const V3_STORES = V1_STORES;
1808
- // Visible for testing
1809
1898
  // Note: DbRemoteDocumentChanges is no longer used and dropped with v9.
1810
1899
  const V4_STORES = [...V3_STORES, DbClientMetadata.store];
1811
1900
  // V5 does not change the set of stores.
@@ -1815,12 +1904,24 @@ const V8_STORES = [...V6_STORES, DbCollectionParent.store];
1815
1904
  // V9 does not change the set of stores.
1816
1905
  // V10 does not change the set of stores.
1817
1906
  const V11_STORES = [...V8_STORES, DbBundle.store, DbNamedQuery.store];
1818
- /**
1819
- * The list of all default IndexedDB stores used throughout the SDK. This is
1820
- * used when creating transactions so that access across all stores is done
1821
- * atomically.
1822
- */
1823
- const ALL_STORES = V11_STORES;
1907
+ const V12_STORES = [
1908
+ ...V11_STORES,
1909
+ DbIndexConfiguration.store,
1910
+ DbIndexState.store,
1911
+ DbIndexEntry.store
1912
+ ];
1913
+ /** Returns the object stores for the provided schema. */
1914
+ function getObjectStores(schemaVersion) {
1915
+ if (schemaVersion === 12) {
1916
+ return V12_STORES;
1917
+ }
1918
+ else if (schemaVersion === 11) {
1919
+ return V11_STORES;
1920
+ }
1921
+ else {
1922
+ fail();
1923
+ }
1924
+ }
1824
1925
 
1825
1926
  /**
1826
1927
  * @license
@@ -2117,6 +2218,15 @@ class SimpleDbTransaction {
2117
2218
  this.transaction.abort();
2118
2219
  }
2119
2220
  }
2221
+ maybeCommit() {
2222
+ // If the browser supports V3 IndexedDB, we invoke commit() explicitly to
2223
+ // speed up index DB processing if the event loop remains blocks.
2224
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2225
+ const maybeV3IndexedDb = this.transaction;
2226
+ if (!this.aborted && typeof maybeV3IndexedDb.commit === 'function') {
2227
+ maybeV3IndexedDb.commit();
2228
+ }
2229
+ }
2120
2230
  /**
2121
2231
  * Returns a SimpleDbStore<KeyType, ValueType> for the specified store. All
2122
2232
  * operations performed on the SimpleDbStore happen within the context of this
@@ -2313,6 +2423,10 @@ class SimpleDb {
2313
2423
  this.db = await this.ensureDb(action);
2314
2424
  const transaction = SimpleDbTransaction.open(this.db, action, readonly ? 'readonly' : 'readwrite', objectStores);
2315
2425
  const transactionFnResult = transactionFn(transaction)
2426
+ .next(result => {
2427
+ transaction.maybeCommit();
2428
+ return result;
2429
+ })
2316
2430
  .catch(error => {
2317
2431
  // Abort the transaction if there was an error.
2318
2432
  transaction.abort(error);
@@ -2485,13 +2599,29 @@ class SimpleDbStore {
2485
2599
  return wrapRequest(request);
2486
2600
  }
2487
2601
  loadAll(indexOrRange, range) {
2488
- const cursor = this.cursor(this.options(indexOrRange, range));
2489
- const results = [];
2490
- return this.iterateCursor(cursor, (key, value) => {
2491
- results.push(value);
2492
- }).next(() => {
2493
- return results;
2494
- });
2602
+ const iterateOptions = this.options(indexOrRange, range);
2603
+ // Use `getAll()` if the browser supports IndexedDB v3, as it is roughly
2604
+ // 20% faster. Unfortunately, getAll() does not support custom indices.
2605
+ if (!iterateOptions.index && typeof this.store.getAll === 'function') {
2606
+ const request = this.store.getAll(iterateOptions.range);
2607
+ return new PersistencePromise((resolve, reject) => {
2608
+ request.onerror = (event) => {
2609
+ reject(event.target.error);
2610
+ };
2611
+ request.onsuccess = (event) => {
2612
+ resolve(event.target.result);
2613
+ };
2614
+ });
2615
+ }
2616
+ else {
2617
+ const cursor = this.cursor(iterateOptions);
2618
+ const results = [];
2619
+ return this.iterateCursor(cursor, (key, value) => {
2620
+ results.push(value);
2621
+ }).next(() => {
2622
+ return results;
2623
+ });
2624
+ }
2495
2625
  }
2496
2626
  deleteAll(indexOrRange, range) {
2497
2627
  logDebug(LOG_TAG$g, 'DELETE ALL', this.store.name);
@@ -4345,12 +4475,12 @@ class FieldIndex {
4345
4475
  /** The collection ID this index applies to. */
4346
4476
  collectionGroup,
4347
4477
  /** The field segments for this index. */
4348
- segments,
4478
+ fields,
4349
4479
  /** Shows how up-to-date the index is for the current user. */
4350
4480
  indexState) {
4351
4481
  this.indexId = indexId;
4352
4482
  this.collectionGroup = collectionGroup;
4353
- this.segments = segments;
4483
+ this.fields = fields;
4354
4484
  this.indexState = indexState;
4355
4485
  }
4356
4486
  }
@@ -4460,27 +4590,29 @@ function newTarget(path, collectionGroup = null, orderBy = [], filters = [], lim
4460
4590
  function canonifyTarget(target) {
4461
4591
  const targetImpl = debugCast(target);
4462
4592
  if (targetImpl.memoizedCanonicalId === null) {
4463
- let canonicalId = targetImpl.path.canonicalString();
4593
+ let str = targetImpl.path.canonicalString();
4464
4594
  if (targetImpl.collectionGroup !== null) {
4465
- canonicalId += '|cg:' + targetImpl.collectionGroup;
4595
+ str += '|cg:' + targetImpl.collectionGroup;
4466
4596
  }
4467
- canonicalId += '|f:';
4468
- canonicalId += targetImpl.filters.map(f => canonifyFilter(f)).join(',');
4469
- canonicalId += '|ob:';
4470
- canonicalId += targetImpl.orderBy.map(o => canonifyOrderBy(o)).join(',');
4597
+ str += '|f:';
4598
+ str += targetImpl.filters.map(f => canonifyFilter(f)).join(',');
4599
+ str += '|ob:';
4600
+ str += targetImpl.orderBy.map(o => canonifyOrderBy(o)).join(',');
4471
4601
  if (!isNullOrUndefined(targetImpl.limit)) {
4472
- canonicalId += '|l:';
4473
- canonicalId += targetImpl.limit;
4602
+ str += '|l:';
4603
+ str += targetImpl.limit;
4474
4604
  }
4475
4605
  if (targetImpl.startAt) {
4476
- canonicalId += '|lb:';
4477
- canonicalId += canonifyBound(targetImpl.startAt);
4606
+ str += '|lb:';
4607
+ str += targetImpl.startAt.inclusive ? 'b:' : 'a:';
4608
+ str += targetImpl.startAt.position.map(p => canonicalId(p)).join(',');
4478
4609
  }
4479
4610
  if (targetImpl.endAt) {
4480
- canonicalId += '|ub:';
4481
- canonicalId += canonifyBound(targetImpl.endAt);
4611
+ str += '|ub:';
4612
+ str += targetImpl.endAt.inclusive ? 'a:' : 'b:';
4613
+ str += targetImpl.endAt.position.map(p => canonicalId(p)).join(',');
4482
4614
  }
4483
- targetImpl.memoizedCanonicalId = canonicalId;
4615
+ targetImpl.memoizedCanonicalId = str;
4484
4616
  }
4485
4617
  return targetImpl.memoizedCanonicalId;
4486
4618
  }
@@ -4503,10 +4635,14 @@ function stringifyTarget(target) {
4503
4635
  .join(', ')}]`;
4504
4636
  }
4505
4637
  if (target.startAt) {
4506
- str += ', startAt: ' + canonifyBound(target.startAt);
4638
+ str += ', startAt: ';
4639
+ str += target.startAt.inclusive ? 'b:' : 'a:';
4640
+ str += target.startAt.position.map(p => canonicalId(p)).join(',');
4507
4641
  }
4508
4642
  if (target.endAt) {
4509
- str += ', endAt: ' + canonifyBound(target.endAt);
4643
+ str += ', endAt: ';
4644
+ str += target.endAt.inclusive ? 'a:' : 'b:';
4645
+ str += target.endAt.position.map(p => canonicalId(p)).join(',');
4510
4646
  }
4511
4647
  return `Target(${str})`;
4512
4648
  }
@@ -4729,7 +4865,6 @@ class ArrayContainsAnyFilter extends FieldFilter {
4729
4865
  return other.arrayValue.values.some(val => arrayValueContains(this.value.arrayValue, val));
4730
4866
  }
4731
4867
  }
4732
- // TODO(indexing): Change Bound.before to "inclusive"
4733
4868
  /**
4734
4869
  * Represents a bound of a query.
4735
4870
  *
@@ -4745,17 +4880,11 @@ class ArrayContainsAnyFilter extends FieldFilter {
4745
4880
  * just after the provided values.
4746
4881
  */
4747
4882
  class Bound {
4748
- constructor(position, before) {
4883
+ constructor(position, inclusive) {
4749
4884
  this.position = position;
4750
- this.before = before;
4885
+ this.inclusive = inclusive;
4751
4886
  }
4752
4887
  }
4753
- function canonifyBound(bound) {
4754
- // TODO(b/29183165): Make this collision robust.
4755
- return `${bound.before ? 'b' : 'a'}:${bound.position
4756
- .map(p => canonicalId(p))
4757
- .join(',')}`;
4758
- }
4759
4888
  /**
4760
4889
  * An ordering on a field, in some Direction. Direction defaults to ASCENDING.
4761
4890
  */
@@ -4775,11 +4904,7 @@ function stringifyOrderBy(orderBy) {
4775
4904
  function orderByEquals(left, right) {
4776
4905
  return left.dir === right.dir && left.field.isEqual(right.field);
4777
4906
  }
4778
- /**
4779
- * Returns true if a document sorts before a bound using the provided sort
4780
- * order.
4781
- */
4782
- function sortsBeforeDocument(bound, orderBy, doc) {
4907
+ function boundCompareToDocument(bound, orderBy, doc) {
4783
4908
  let comparison = 0;
4784
4909
  for (let i = 0; i < bound.position.length; i++) {
4785
4910
  const orderByComponent = orderBy[i];
@@ -4798,7 +4923,23 @@ function sortsBeforeDocument(bound, orderBy, doc) {
4798
4923
  break;
4799
4924
  }
4800
4925
  }
4801
- return bound.before ? comparison <= 0 : comparison < 0;
4926
+ return comparison;
4927
+ }
4928
+ /**
4929
+ * Returns true if a document sorts after a bound using the provided sort
4930
+ * order.
4931
+ */
4932
+ function boundSortsAfterDocument(bound, orderBy, doc) {
4933
+ const comparison = boundCompareToDocument(bound, orderBy, doc);
4934
+ return bound.inclusive ? comparison >= 0 : comparison > 0;
4935
+ }
4936
+ /**
4937
+ * Returns true if a document sorts before a bound using the provided sort
4938
+ * order.
4939
+ */
4940
+ function boundSortsBeforeDocument(bound, orderBy, doc) {
4941
+ const comparison = boundCompareToDocument(bound, orderBy, doc);
4942
+ return bound.inclusive ? comparison <= 0 : comparison < 0;
4802
4943
  }
4803
4944
  function boundEquals(left, right) {
4804
4945
  if (left === null) {
@@ -4807,7 +4948,7 @@ function boundEquals(left, right) {
4807
4948
  else if (right === null) {
4808
4949
  return false;
4809
4950
  }
4810
- if (left.before !== right.before ||
4951
+ if (left.inclusive !== right.inclusive ||
4811
4952
  left.position.length !== right.position.length) {
4812
4953
  return false;
4813
4954
  }
@@ -5011,10 +5152,10 @@ function queryToTarget(query) {
5011
5152
  }
5012
5153
  // We need to swap the cursors to match the now-flipped query ordering.
5013
5154
  const startAt = queryImpl.endAt
5014
- ? new Bound(queryImpl.endAt.position, !queryImpl.endAt.before)
5155
+ ? new Bound(queryImpl.endAt.position, !queryImpl.endAt.inclusive)
5015
5156
  : null;
5016
5157
  const endAt = queryImpl.startAt
5017
- ? new Bound(queryImpl.startAt.position, !queryImpl.startAt.before)
5158
+ ? new Bound(queryImpl.startAt.position, !queryImpl.startAt.inclusive)
5018
5159
  : null;
5019
5160
  // Now return as a LimitType.First query.
5020
5161
  queryImpl.memoizedTarget = newTarget(queryImpl.path, queryImpl.collectionGroup, orderBys, queryImpl.filters, queryImpl.limit, startAt, endAt);
@@ -5102,11 +5243,11 @@ function queryMatchesFilters(query, doc) {
5102
5243
  /** Makes sure a document is within the bounds, if provided. */
5103
5244
  function queryMatchesBounds(query, doc) {
5104
5245
  if (query.startAt &&
5105
- !sortsBeforeDocument(query.startAt, queryOrderBy(query), doc)) {
5246
+ !boundSortsBeforeDocument(query.startAt, queryOrderBy(query), doc)) {
5106
5247
  return false;
5107
5248
  }
5108
5249
  if (query.endAt &&
5109
- sortsBeforeDocument(query.endAt, queryOrderBy(query), doc)) {
5250
+ !boundSortsAfterDocument(query.endAt, queryOrderBy(query), doc)) {
5110
5251
  return false;
5111
5252
  }
5112
5253
  return true;
@@ -7985,10 +8126,10 @@ function toQueryTarget(serializer, target) {
7985
8126
  result.structuredQuery.limit = limit;
7986
8127
  }
7987
8128
  if (target.startAt) {
7988
- result.structuredQuery.startAt = toCursor(target.startAt);
8129
+ result.structuredQuery.startAt = toStartAtCursor(target.startAt);
7989
8130
  }
7990
8131
  if (target.endAt) {
7991
- result.structuredQuery.endAt = toCursor(target.endAt);
8132
+ result.structuredQuery.endAt = toEndAtCursor(target.endAt);
7992
8133
  }
7993
8134
  return result;
7994
8135
  }
@@ -8021,11 +8162,11 @@ function convertQueryTargetToQuery(target) {
8021
8162
  }
8022
8163
  let startAt = null;
8023
8164
  if (query.startAt) {
8024
- startAt = fromCursor(query.startAt);
8165
+ startAt = fromStartAtCursor(query.startAt);
8025
8166
  }
8026
8167
  let endAt = null;
8027
8168
  if (query.endAt) {
8028
- endAt = fromCursor(query.endAt);
8169
+ endAt = fromEndAtCursor(query.endAt);
8029
8170
  }
8030
8171
  return newQuery(path, collectionGroup, orderBy, filterBy, limit, "F" /* First */, startAt, endAt);
8031
8172
  }
@@ -8116,16 +8257,27 @@ function toOrder(orderBys) {
8116
8257
  function fromOrder(orderBys) {
8117
8258
  return orderBys.map(order => fromPropertyOrder(order));
8118
8259
  }
8119
- function toCursor(cursor) {
8260
+ function toStartAtCursor(cursor) {
8120
8261
  return {
8121
- before: cursor.before,
8262
+ before: cursor.inclusive,
8122
8263
  values: cursor.position
8123
8264
  };
8124
8265
  }
8125
- function fromCursor(cursor) {
8126
- const before = !!cursor.before;
8266
+ function toEndAtCursor(cursor) {
8267
+ return {
8268
+ before: !cursor.inclusive,
8269
+ values: cursor.position
8270
+ };
8271
+ }
8272
+ function fromStartAtCursor(cursor) {
8273
+ const inclusive = !!cursor.before;
8274
+ const position = cursor.values || [];
8275
+ return new Bound(position, inclusive);
8276
+ }
8277
+ function fromEndAtCursor(cursor) {
8278
+ const inclusive = !cursor.before;
8127
8279
  const position = cursor.values || [];
8128
- return new Bound(position, before);
8280
+ return new Bound(position, inclusive);
8129
8281
  }
8130
8282
  // visible for testing
8131
8283
  function toDirection(dir) {
@@ -8589,6 +8741,19 @@ function fromBundleMetadata(metadata) {
8589
8741
  version: metadata.version,
8590
8742
  createTime: fromVersion(metadata.createTime)
8591
8743
  };
8744
+ }
8745
+ function toDbIndexConfiguration(index) {
8746
+ return new DbIndexConfiguration(index.indexId, index.collectionGroup, index.fields.map(s => [s.fieldPath.canonicalString(), s.kind]));
8747
+ }
8748
+ function fromDbIndexConfiguration(index, state) {
8749
+ const decodedState = state
8750
+ ? new IndexState(state.sequenceNumber, new IndexOffset(fromDbTimestamp(state.readTime), new DocumentKey(decodeResourcePath(state.documentKey)), state.largestBatchId))
8751
+ : IndexState.empty();
8752
+ const decodedSegments = index.fields.map(([fieldPath, kind]) => new IndexSegment(FieldPath$1.fromServerFormat(fieldPath), kind));
8753
+ return new FieldIndex(index.indexId, index.collectionGroup, decodedSegments, decodedState);
8754
+ }
8755
+ function toDbIndexState(indexId, user, sequenceNumber, offset) {
8756
+ return new DbIndexState(indexId, user.uid || '', sequenceNumber, toDbTimestamp(offset.readTime), encodeResourcePath(offset.documentKey.path), offset.largestBatchId);
8592
8757
  }
8593
8758
 
8594
8759
  /**
@@ -8678,6 +8843,38 @@ class MemoryIndexManager {
8678
8843
  getCollectionParents(transaction, collectionId) {
8679
8844
  return PersistencePromise.resolve(this.collectionParentIndex.getEntries(collectionId));
8680
8845
  }
8846
+ addFieldIndex(transaction, index) {
8847
+ // Field indices are not supported with memory persistence.
8848
+ return PersistencePromise.resolve();
8849
+ }
8850
+ deleteFieldIndex(transaction, index) {
8851
+ // Field indices are not supported with memory persistence.
8852
+ return PersistencePromise.resolve();
8853
+ }
8854
+ getDocumentsMatchingTarget(transaction, fieldIndex, target) {
8855
+ // Field indices are not supported with memory persistence.
8856
+ return PersistencePromise.resolve(documentKeySet());
8857
+ }
8858
+ getFieldIndex(transaction, target) {
8859
+ // Field indices are not supported with memory persistence.
8860
+ return PersistencePromise.resolve(null);
8861
+ }
8862
+ getFieldIndexes(transaction, collectionGroup) {
8863
+ // Field indices are not supported with memory persistence.
8864
+ return PersistencePromise.resolve([]);
8865
+ }
8866
+ getNextCollectionGroupToUpdate(transaction) {
8867
+ // Field indices are not supported with memory persistence.
8868
+ return PersistencePromise.resolve(null);
8869
+ }
8870
+ updateCollectionGroup(transaction, collectionGroup, offset) {
8871
+ // Field indices are not supported with memory persistence.
8872
+ return PersistencePromise.resolve();
8873
+ }
8874
+ updateIndexEntries(transaction, documents) {
8875
+ // Field indices are not supported with memory persistence.
8876
+ return PersistencePromise.resolve();
8877
+ }
8681
8878
  }
8682
8879
  /**
8683
8880
  * Internal implementation of the collection-parent index exposed by MemoryIndexManager.
@@ -8729,17 +8926,22 @@ class MemoryCollectionParentIndex {
8729
8926
  */
8730
8927
  /**
8731
8928
  * A persisted implementation of IndexManager.
8929
+ *
8930
+ * PORTING NOTE: Unlike iOS and Android, the Web SDK does not memoize index
8931
+ * data as it supports multi-tab access.
8732
8932
  */
8733
8933
  class IndexedDbIndexManager {
8734
- constructor() {
8934
+ constructor(user) {
8935
+ this.user = user;
8735
8936
  /**
8736
8937
  * An in-memory copy of the index entries we've already written since the SDK
8737
8938
  * launched. Used to avoid re-writing the same entry repeatedly.
8738
8939
  *
8739
- * This is *NOT* a complete cache of what's in persistence and so can never be used to
8740
- * satisfy reads.
8940
+ * This is *NOT* a complete cache of what's in persistence and so can never be
8941
+ * used to satisfy reads.
8741
8942
  */
8742
8943
  this.collectionParentsCache = new MemoryCollectionParentIndex();
8944
+ this.uid = user.uid || '';
8743
8945
  }
8744
8946
  /**
8745
8947
  * Adds a new entry to the collection parent index.
@@ -8786,6 +8988,85 @@ class IndexedDbIndexManager {
8786
8988
  return parentPaths;
8787
8989
  });
8788
8990
  }
8991
+ addFieldIndex(transaction, index) {
8992
+ // TODO(indexing): Verify that the auto-incrementing index ID works in
8993
+ // Safari & Firefox.
8994
+ const indexes = indexConfigurationStore(transaction);
8995
+ const dbIndex = toDbIndexConfiguration(index);
8996
+ delete dbIndex.indexId; // `indexId` is auto-populated by IndexedDb
8997
+ return indexes.add(dbIndex).next();
8998
+ }
8999
+ deleteFieldIndex(transaction, index) {
9000
+ const indexes = indexConfigurationStore(transaction);
9001
+ const states = indexStateStore(transaction);
9002
+ const entries = indexEntriesStore(transaction);
9003
+ return indexes
9004
+ .delete(index.indexId)
9005
+ .next(() => states.delete(IDBKeyRange.bound([index.indexId], [index.indexId + 1],
9006
+ /*lowerOpen=*/ false,
9007
+ /*upperOpen=*/ true)))
9008
+ .next(() => entries.delete(IDBKeyRange.bound([index.indexId], [index.indexId + 1],
9009
+ /*lowerOpen=*/ false,
9010
+ /*upperOpen=*/ true)));
9011
+ }
9012
+ getDocumentsMatchingTarget(transaction, fieldIndex, target) {
9013
+ // TODO(indexing): Implement
9014
+ return PersistencePromise.resolve(documentKeySet());
9015
+ }
9016
+ getFieldIndex(transaction, target) {
9017
+ // TODO(indexing): Implement
9018
+ return PersistencePromise.resolve(null);
9019
+ }
9020
+ getFieldIndexes(transaction, collectionGroup) {
9021
+ const indexes = indexConfigurationStore(transaction);
9022
+ const states = indexStateStore(transaction);
9023
+ return (collectionGroup
9024
+ ? indexes.loadAll(DbIndexConfiguration.collectionGroupIndex, IDBKeyRange.bound(collectionGroup, collectionGroup))
9025
+ : indexes.loadAll()).next(indexConfigs => {
9026
+ const result = [];
9027
+ return PersistencePromise.forEach(indexConfigs, (indexConfig) => {
9028
+ return states
9029
+ .get([indexConfig.indexId, this.uid])
9030
+ .next(indexState => {
9031
+ result.push(fromDbIndexConfiguration(indexConfig, indexState));
9032
+ });
9033
+ }).next(() => result);
9034
+ });
9035
+ }
9036
+ getNextCollectionGroupToUpdate(transaction) {
9037
+ return this.getFieldIndexes(transaction).next(indexes => {
9038
+ if (indexes.length === 0) {
9039
+ return null;
9040
+ }
9041
+ indexes.sort((l, r) => l.indexState.sequenceNumber - r.indexState.sequenceNumber);
9042
+ return indexes[0].collectionGroup;
9043
+ });
9044
+ }
9045
+ updateCollectionGroup(transaction, collectionGroup, offset) {
9046
+ const indexes = indexConfigurationStore(transaction);
9047
+ const states = indexStateStore(transaction);
9048
+ return this.getNextSequenceNumber(transaction).next(nextSequenceNumber => indexes
9049
+ .loadAll(DbIndexConfiguration.collectionGroupIndex, IDBKeyRange.bound(collectionGroup, collectionGroup))
9050
+ .next(configs => PersistencePromise.forEach(configs, (config) => states.put(toDbIndexState(config.indexId, this.user, nextSequenceNumber, offset)))));
9051
+ }
9052
+ updateIndexEntries(transaction, documents) {
9053
+ // TODO(indexing): Implement
9054
+ return PersistencePromise.resolve();
9055
+ }
9056
+ getNextSequenceNumber(transaction) {
9057
+ let nextSequenceNumber = 1;
9058
+ const states = indexStateStore(transaction);
9059
+ return states
9060
+ .iterate({
9061
+ index: DbIndexState.sequenceNumberIndex,
9062
+ reverse: true,
9063
+ range: IDBKeyRange.upperBound([this.uid, Number.MAX_SAFE_INTEGER])
9064
+ }, (_, state, controller) => {
9065
+ controller.done();
9066
+ nextSequenceNumber = state.sequenceNumber + 1;
9067
+ })
9068
+ .next(() => nextSequenceNumber);
9069
+ }
8789
9070
  }
8790
9071
  /**
8791
9072
  * Helper to get a typed SimpleDbStore for the collectionParents
@@ -8793,6 +9074,24 @@ class IndexedDbIndexManager {
8793
9074
  */
8794
9075
  function collectionParentsStore(txn) {
8795
9076
  return getStore(txn, DbCollectionParent.store);
9077
+ }
9078
+ /**
9079
+ * Helper to get a typed SimpleDbStore for the index entry object store.
9080
+ */
9081
+ function indexEntriesStore(txn) {
9082
+ return getStore(txn, DbIndexEntry.store);
9083
+ }
9084
+ /**
9085
+ * Helper to get a typed SimpleDbStore for the index configuration object store.
9086
+ */
9087
+ function indexConfigurationStore(txn) {
9088
+ return getStore(txn, DbIndexConfiguration.store);
9089
+ }
9090
+ /**
9091
+ * Helper to get a typed SimpleDbStore for the index state object store.
9092
+ */
9093
+ function indexStateStore(txn) {
9094
+ return getStore(txn, DbIndexState.store);
8796
9095
  }
8797
9096
 
8798
9097
  /**
@@ -10262,12 +10561,10 @@ class RemoteDocumentChangeBuffer {
10262
10561
  * `newIndexedDbRemoteDocumentCache()`.
10263
10562
  */
10264
10563
  class IndexedDbRemoteDocumentCacheImpl {
10265
- /**
10266
- * @param serializer - The document serializer.
10267
- * @param indexManager - The query indexes that need to be maintained.
10268
- */
10269
- constructor(serializer, indexManager) {
10564
+ constructor(serializer) {
10270
10565
  this.serializer = serializer;
10566
+ }
10567
+ setIndexManager(indexManager) {
10271
10568
  this.indexManager = indexManager;
10272
10569
  }
10273
10570
  /**
@@ -10389,21 +10686,21 @@ class IndexedDbRemoteDocumentCacheImpl {
10389
10686
  }
10390
10687
  });
10391
10688
  }
10392
- getDocumentsMatchingQuery(transaction, query, sinceReadTime) {
10689
+ getAll(transaction, collection, sinceReadTime) {
10393
10690
  let results = mutableDocumentMap();
10394
- const immediateChildrenPathLength = query.path.length + 1;
10691
+ const immediateChildrenPathLength = collection.length + 1;
10395
10692
  const iterationOptions = {};
10396
10693
  if (sinceReadTime.isEqual(SnapshotVersion.min())) {
10397
10694
  // Documents are ordered by key, so we can use a prefix scan to narrow
10398
10695
  // down the documents we need to match the query against.
10399
- const startKey = query.path.toArray();
10696
+ const startKey = collection.toArray();
10400
10697
  iterationOptions.range = IDBKeyRange.lowerBound(startKey);
10401
10698
  }
10402
10699
  else {
10403
10700
  // Execute an index-free query and filter by read time. This is safe
10404
10701
  // since all document changes to queries that have a
10405
10702
  // lastLimboFreeSnapshotVersion (`sinceReadTime`) have a read time set.
10406
- const collectionKey = query.path.toArray();
10703
+ const collectionKey = collection.toArray();
10407
10704
  const readTimeKey = toDbTimestampKey(sinceReadTime);
10408
10705
  iterationOptions.range = IDBKeyRange.lowerBound([collectionKey, readTimeKey],
10409
10706
  /* open= */ true);
@@ -10420,12 +10717,12 @@ class IndexedDbRemoteDocumentCacheImpl {
10420
10717
  return;
10421
10718
  }
10422
10719
  const document = this.maybeDecodeDocument(DocumentKey.fromSegments(key), dbRemoteDoc);
10423
- if (!query.path.isPrefixOf(document.key.path)) {
10424
- control.done();
10425
- }
10426
- else if (queryMatches(query, document)) {
10720
+ if (collection.isPrefixOf(document.key.path)) {
10427
10721
  results = results.insert(document.key, document);
10428
10722
  }
10723
+ else {
10724
+ control.done();
10725
+ }
10429
10726
  })
10430
10727
  .next(() => results);
10431
10728
  }
@@ -10463,14 +10760,9 @@ class IndexedDbRemoteDocumentCacheImpl {
10463
10760
  return MutableDocument.newInvalidDocument(documentKey);
10464
10761
  }
10465
10762
  }
10466
- /**
10467
- * Creates a new IndexedDbRemoteDocumentCache.
10468
- *
10469
- * @param serializer - The document serializer.
10470
- * @param indexManager - The query indexes that need to be maintained.
10471
- */
10472
- function newIndexedDbRemoteDocumentCache(serializer, indexManager) {
10473
- return new IndexedDbRemoteDocumentCacheImpl(serializer, indexManager);
10763
+ /** Creates a new IndexedDbRemoteDocumentCache. */
10764
+ function newIndexedDbRemoteDocumentCache(serializer) {
10765
+ return new IndexedDbRemoteDocumentCacheImpl(serializer);
10474
10766
  }
10475
10767
  /**
10476
10768
  * Returns the set of documents that have changed since the specified read
@@ -10637,9 +10929,6 @@ class SchemaConverter {
10637
10929
  * and local feature development.
10638
10930
  */
10639
10931
  createOrUpgrade(db, txn, fromVersion, toVersion) {
10640
- hardAssert(fromVersion < toVersion &&
10641
- fromVersion >= 0 &&
10642
- toVersion <= SCHEMA_VERSION);
10643
10932
  const simpleDbTransaction = new SimpleDbTransaction('createOrUpgrade', txn);
10644
10933
  if (fromVersion < 1 && toVersion >= 1) {
10645
10934
  createPrimaryClientStore(db);
@@ -10706,6 +10995,11 @@ class SchemaConverter {
10706
10995
  createNamedQueriesStore(db);
10707
10996
  });
10708
10997
  }
10998
+ if (fromVersion < 12 && toVersion >= 12) {
10999
+ p = p.next(() => {
11000
+ createFieldIndex(db);
11001
+ });
11002
+ }
10709
11003
  return p;
10710
11004
  }
10711
11005
  addDocumentGlobal(txn) {
@@ -10912,6 +11206,20 @@ function createNamedQueriesStore(db) {
10912
11206
  db.createObjectStore(DbNamedQuery.store, {
10913
11207
  keyPath: DbNamedQuery.keyPath
10914
11208
  });
11209
+ }
11210
+ function createFieldIndex(db) {
11211
+ const indexConfiguratioStore = db.createObjectStore(DbIndexConfiguration.store, {
11212
+ keyPath: DbIndexConfiguration.keyPath,
11213
+ autoIncrement: true
11214
+ });
11215
+ indexConfiguratioStore.createIndex(DbIndexConfiguration.collectionGroupIndex, DbIndexConfiguration.collectionGroupIndexPath, { unique: false });
11216
+ const indexStateStore = db.createObjectStore(DbIndexState.store, {
11217
+ keyPath: DbIndexState.keyPath
11218
+ });
11219
+ indexStateStore.createIndex(DbIndexState.sequenceNumberIndex, DbIndexState.sequenceNumberIndexPath, { unique: false });
11220
+ db.createObjectStore(DbIndexEntry.store, {
11221
+ keyPath: DbIndexEntry.keyPath
11222
+ });
10915
11223
  }
10916
11224
 
10917
11225
  /**
@@ -11023,7 +11331,7 @@ class IndexedDbPersistence {
11023
11331
  * If set to true, forcefully obtains database access. Existing tabs will
11024
11332
  * no longer be able to access IndexedDB.
11025
11333
  */
11026
- forceOwningTab) {
11334
+ forceOwningTab, schemaVersion = SCHEMA_VERSION) {
11027
11335
  this.allowTabSynchronization = allowTabSynchronization;
11028
11336
  this.persistenceKey = persistenceKey;
11029
11337
  this.clientId = clientId;
@@ -11032,6 +11340,7 @@ class IndexedDbPersistence {
11032
11340
  this.document = document;
11033
11341
  this.sequenceNumberSyncer = sequenceNumberSyncer;
11034
11342
  this.forceOwningTab = forceOwningTab;
11343
+ this.schemaVersion = schemaVersion;
11035
11344
  this.listenSequence = null;
11036
11345
  this._started = false;
11037
11346
  this.isPrimary = false;
@@ -11053,10 +11362,9 @@ class IndexedDbPersistence {
11053
11362
  this.referenceDelegate = new IndexedDbLruDelegateImpl(this, lruParams);
11054
11363
  this.dbName = persistenceKey + MAIN_DATABASE;
11055
11364
  this.serializer = new LocalSerializer(serializer);
11056
- this.simpleDb = new SimpleDb(this.dbName, SCHEMA_VERSION, new SchemaConverter(this.serializer));
11365
+ this.simpleDb = new SimpleDb(this.dbName, this.schemaVersion, new SchemaConverter(this.serializer));
11057
11366
  this.targetCache = new IndexedDbTargetCache(this.referenceDelegate, this.serializer);
11058
- this.indexManager = new IndexedDbIndexManager();
11059
- this.remoteDocumentCache = newIndexedDbRemoteDocumentCache(this.serializer, this.indexManager);
11367
+ this.remoteDocumentCache = newIndexedDbRemoteDocumentCache(this.serializer);
11060
11368
  this.bundleCache = new IndexedDbBundleCache();
11061
11369
  if (this.window && this.window.localStorage) {
11062
11370
  this.webStorage = this.window.localStorage;
@@ -11392,8 +11700,8 @@ class IndexedDbPersistence {
11392
11700
  get started() {
11393
11701
  return this._started;
11394
11702
  }
11395
- getMutationQueue(user) {
11396
- return IndexedDbMutationQueue.forUser(user, this.serializer, this.indexManager, this.referenceDelegate);
11703
+ getMutationQueue(user, indexManager) {
11704
+ return IndexedDbMutationQueue.forUser(user, this.serializer, indexManager, this.referenceDelegate);
11397
11705
  }
11398
11706
  getTargetCache() {
11399
11707
  return this.targetCache;
@@ -11401,8 +11709,8 @@ class IndexedDbPersistence {
11401
11709
  getRemoteDocumentCache() {
11402
11710
  return this.remoteDocumentCache;
11403
11711
  }
11404
- getIndexManager() {
11405
- return this.indexManager;
11712
+ getIndexManager(user) {
11713
+ return new IndexedDbIndexManager(user);
11406
11714
  }
11407
11715
  getBundleCache() {
11408
11716
  return this.bundleCache;
@@ -11410,11 +11718,12 @@ class IndexedDbPersistence {
11410
11718
  runTransaction(action, mode, transactionOperation) {
11411
11719
  logDebug(LOG_TAG$d, 'Starting transaction:', action);
11412
11720
  const simpleDbMode = mode === 'readonly' ? 'readonly' : 'readwrite';
11721
+ const objectStores = getObjectStores(this.schemaVersion);
11413
11722
  let persistenceTransaction;
11414
11723
  // Do all transactions as readwrite against all object stores, since we
11415
11724
  // are the only reader/writer.
11416
11725
  return this.simpleDb
11417
- .runTransaction(action, simpleDbMode, ALL_STORES, simpleDbTxn => {
11726
+ .runTransaction(action, simpleDbMode, objectStores, simpleDbTxn => {
11418
11727
  persistenceTransaction = new IndexedDbTransaction(simpleDbTxn, this.listenSequence
11419
11728
  ? this.listenSequence.next()
11420
11729
  : ListenSequence.INVALID);
@@ -11786,39 +12095,28 @@ class LocalDocumentsView {
11786
12095
  getDocumentsMatchingCollectionQuery(transaction, query, sinceReadTime) {
11787
12096
  // Query the remote documents and overlay mutations.
11788
12097
  let results;
11789
- let mutationBatches;
11790
12098
  return this.remoteDocumentCache
11791
- .getDocumentsMatchingQuery(transaction, query, sinceReadTime)
12099
+ .getAll(transaction, query.path, sinceReadTime)
11792
12100
  .next(queryResults => {
11793
12101
  results = queryResults;
11794
12102
  return this.mutationQueue.getAllMutationBatchesAffectingQuery(transaction, query);
11795
12103
  })
11796
- .next(matchingMutationBatches => {
11797
- mutationBatches = matchingMutationBatches;
11798
- // It is possible that a PatchMutation can make a document match a query, even if
11799
- // the version in the RemoteDocumentCache is not a match yet (waiting for server
11800
- // to ack). To handle this, we find all document keys affected by the PatchMutations
11801
- // that are not in `result` yet, and back fill them via `remoteDocumentCache.getEntries`,
11802
- // otherwise those `PatchMutations` will be ignored because no base document can be found,
11803
- // and lead to missing result for the query.
11804
- return this.addMissingBaseDocuments(transaction, mutationBatches, results).next(mergedDocuments => {
11805
- results = mergedDocuments;
11806
- for (const batch of mutationBatches) {
11807
- for (const mutation of batch.mutations) {
11808
- const key = mutation.key;
11809
- let document = results.get(key);
11810
- if (document == null) {
11811
- // Create invalid document to apply mutations on top of
11812
- document = MutableDocument.newInvalidDocument(key);
11813
- results = results.insert(key, document);
11814
- }
11815
- mutationApplyToLocalView(mutation, document, batch.localWriteTime);
11816
- if (!document.isFoundDocument()) {
11817
- results = results.remove(key);
11818
- }
12104
+ .next(mutationBatches => {
12105
+ for (const batch of mutationBatches) {
12106
+ for (const mutation of batch.mutations) {
12107
+ const key = mutation.key;
12108
+ let document = results.get(key);
12109
+ if (document == null) {
12110
+ // Create invalid document to apply mutations on top of
12111
+ document = MutableDocument.newInvalidDocument(key);
12112
+ results = results.insert(key, document);
12113
+ }
12114
+ mutationApplyToLocalView(mutation, document, batch.localWriteTime);
12115
+ if (!document.isFoundDocument()) {
12116
+ results = results.remove(key);
11819
12117
  }
11820
12118
  }
11821
- });
12119
+ }
11822
12120
  })
11823
12121
  .next(() => {
11824
12122
  // Finally, filter out any documents that don't actually match
@@ -11831,29 +12129,6 @@ class LocalDocumentsView {
11831
12129
  return results;
11832
12130
  });
11833
12131
  }
11834
- addMissingBaseDocuments(transaction, matchingMutationBatches, existingDocuments) {
11835
- let missingBaseDocEntriesForPatching = documentKeySet();
11836
- for (const batch of matchingMutationBatches) {
11837
- for (const mutation of batch.mutations) {
11838
- if (mutation instanceof PatchMutation &&
11839
- existingDocuments.get(mutation.key) === null) {
11840
- missingBaseDocEntriesForPatching =
11841
- missingBaseDocEntriesForPatching.add(mutation.key);
11842
- }
11843
- }
11844
- }
11845
- let mergedDocuments = existingDocuments;
11846
- return this.remoteDocumentCache
11847
- .getEntries(transaction, missingBaseDocEntriesForPatching)
11848
- .next(missingBaseDocs => {
11849
- missingBaseDocs.forEach((key, doc) => {
11850
- if (doc.isFoundDocument()) {
11851
- mergedDocuments = mergedDocuments.insert(key, doc);
11852
- }
11853
- });
11854
- return mergedDocuments;
11855
- });
11856
- }
11857
12132
  }
11858
12133
 
11859
12134
  /**
@@ -11912,11 +12187,18 @@ class LocalStoreImpl {
11912
12187
  * PORTING NOTE: This is only used for multi-tab synchronization.
11913
12188
  */
11914
12189
  this.lastDocumentChangeReadTime = SnapshotVersion.min();
11915
- this.mutationQueue = persistence.getMutationQueue(initialUser);
11916
12190
  this.remoteDocuments = persistence.getRemoteDocumentCache();
11917
12191
  this.targetCache = persistence.getTargetCache();
11918
- this.localDocuments = new LocalDocumentsView(this.remoteDocuments, this.mutationQueue, this.persistence.getIndexManager());
11919
12192
  this.bundleCache = persistence.getBundleCache();
12193
+ this.initializeUserComponents(initialUser);
12194
+ }
12195
+ initializeUserComponents(user) {
12196
+ // TODO(indexing): Add spec tests that test these components change after a
12197
+ // user change
12198
+ this.indexManager = this.persistence.getIndexManager(user);
12199
+ this.mutationQueue = this.persistence.getMutationQueue(user, this.indexManager);
12200
+ this.localDocuments = new LocalDocumentsView(this.remoteDocuments, this.mutationQueue, this.indexManager);
12201
+ this.remoteDocuments.setIndexManager(this.indexManager);
11920
12202
  this.queryEngine.setLocalDocumentsView(this.localDocuments);
11921
12203
  }
11922
12204
  collectGarbage(garbageCollector) {
@@ -11938,8 +12220,6 @@ persistence, queryEngine, initialUser, serializer) {
11938
12220
  // change.
11939
12221
  async function localStoreHandleUserChange(localStore, user) {
11940
12222
  const localStoreImpl = debugCast(localStore);
11941
- let newMutationQueue = localStoreImpl.mutationQueue;
11942
- let newLocalDocuments = localStoreImpl.localDocuments;
11943
12223
  const result = await localStoreImpl.persistence.runTransaction('Handle user change', 'readonly', txn => {
11944
12224
  // Swap out the mutation queue, grabbing the pending mutation batches
11945
12225
  // before and after.
@@ -11948,11 +12228,8 @@ async function localStoreHandleUserChange(localStore, user) {
11948
12228
  .getAllMutationBatches(txn)
11949
12229
  .next(promisedOldBatches => {
11950
12230
  oldBatches = promisedOldBatches;
11951
- newMutationQueue = localStoreImpl.persistence.getMutationQueue(user);
11952
- // Recreate our LocalDocumentsView using the new
11953
- // MutationQueue.
11954
- newLocalDocuments = new LocalDocumentsView(localStoreImpl.remoteDocuments, newMutationQueue, localStoreImpl.persistence.getIndexManager());
11955
- return newMutationQueue.getAllMutationBatches(txn);
12231
+ localStoreImpl.initializeUserComponents(user);
12232
+ return localStoreImpl.mutationQueue.getAllMutationBatches(txn);
11956
12233
  })
11957
12234
  .next(newBatches => {
11958
12235
  const removedBatchIds = [];
@@ -11973,7 +12250,7 @@ async function localStoreHandleUserChange(localStore, user) {
11973
12250
  }
11974
12251
  // Return the set of all (potentially) changed documents and the list
11975
12252
  // of mutation batch IDs that were affected by change.
11976
- return newLocalDocuments
12253
+ return localStoreImpl.localDocuments
11977
12254
  .getDocuments(txn, changedKeys)
11978
12255
  .next(affectedDocuments => {
11979
12256
  return {
@@ -11984,9 +12261,6 @@ async function localStoreHandleUserChange(localStore, user) {
11984
12261
  });
11985
12262
  });
11986
12263
  });
11987
- localStoreImpl.mutationQueue = newMutationQueue;
11988
- localStoreImpl.localDocuments = newLocalDocuments;
11989
- localStoreImpl.queryEngine.setLocalDocumentsView(localStoreImpl.localDocuments);
11990
12264
  return result;
11991
12265
  }
11992
12266
  /* Accepts locally generated Mutations and commit them to storage. */
@@ -13052,14 +13326,16 @@ class MemoryRemoteDocumentCacheImpl {
13052
13326
  * expected to just return 0 to avoid unnecessarily doing the work of
13053
13327
  * calculating the size.
13054
13328
  */
13055
- constructor(indexManager, sizer) {
13056
- this.indexManager = indexManager;
13329
+ constructor(sizer) {
13057
13330
  this.sizer = sizer;
13058
13331
  /** Underlying cache of documents and their read times. */
13059
13332
  this.docs = documentEntryMap();
13060
13333
  /** Size of all cached documents. */
13061
13334
  this.size = 0;
13062
13335
  }
13336
+ setIndexManager(indexManager) {
13337
+ this.indexManager = indexManager;
13338
+ }
13063
13339
  /**
13064
13340
  * Adds the supplied entry to the cache and updates the cache size as appropriate.
13065
13341
  *
@@ -13107,21 +13383,22 @@ class MemoryRemoteDocumentCacheImpl {
13107
13383
  });
13108
13384
  return PersistencePromise.resolve(results);
13109
13385
  }
13110
- getDocumentsMatchingQuery(transaction, query, sinceReadTime) {
13386
+ getAll(transaction, collectionPath, sinceReadTime) {
13111
13387
  let results = mutableDocumentMap();
13112
13388
  // Documents are ordered by key, so we can use a prefix scan to narrow down
13113
13389
  // the documents we need to match the query against.
13114
- const prefix = new DocumentKey(query.path.child(''));
13390
+ const prefix = new DocumentKey(collectionPath.child(''));
13115
13391
  const iterator = this.docs.getIteratorFrom(prefix);
13116
13392
  while (iterator.hasNext()) {
13117
13393
  const { key, value: { document } } = iterator.getNext();
13118
- if (!query.path.isPrefixOf(key.path)) {
13394
+ if (!collectionPath.isPrefixOf(key.path)) {
13119
13395
  break;
13120
13396
  }
13121
- if (document.readTime.compareTo(sinceReadTime) <= 0) {
13397
+ if (key.path.length > collectionPath.length + 1) {
13398
+ // Exclude entries from subcollections.
13122
13399
  continue;
13123
13400
  }
13124
- if (!queryMatches(query, document)) {
13401
+ if (document.readTime.compareTo(sinceReadTime) <= 0) {
13125
13402
  continue;
13126
13403
  }
13127
13404
  results = results.insert(document.key, document.mutableCopy());
@@ -13143,13 +13420,12 @@ class MemoryRemoteDocumentCacheImpl {
13143
13420
  /**
13144
13421
  * Creates a new memory-only RemoteDocumentCache.
13145
13422
  *
13146
- * @param indexManager - A class that manages collection group indices.
13147
13423
  * @param sizer - Used to assess the size of a document. For eager GC, this is
13148
13424
  * expected to just return 0 to avoid unnecessarily doing the work of
13149
13425
  * calculating the size.
13150
13426
  */
13151
- function newMemoryRemoteDocumentCache(indexManager, sizer) {
13152
- return new MemoryRemoteDocumentCacheImpl(indexManager, sizer);
13427
+ function newMemoryRemoteDocumentCache(sizer) {
13428
+ return new MemoryRemoteDocumentCacheImpl(sizer);
13153
13429
  }
13154
13430
  /**
13155
13431
  * Handles the details of adding and updating documents in the MemoryRemoteDocumentCache.
@@ -13350,7 +13626,7 @@ class MemoryPersistence {
13350
13626
  this.targetCache = new MemoryTargetCache(this);
13351
13627
  const sizer = (doc) => this.referenceDelegate.documentSize(doc);
13352
13628
  this.indexManager = new MemoryIndexManager();
13353
- this.remoteDocumentCache = newMemoryRemoteDocumentCache(this.indexManager, sizer);
13629
+ this.remoteDocumentCache = newMemoryRemoteDocumentCache(sizer);
13354
13630
  this.serializer = new LocalSerializer(serializer);
13355
13631
  this.bundleCache = new MemoryBundleCache(this.serializer);
13356
13632
  }
@@ -13371,13 +13647,15 @@ class MemoryPersistence {
13371
13647
  setNetworkEnabled() {
13372
13648
  // No op.
13373
13649
  }
13374
- getIndexManager() {
13650
+ getIndexManager(user) {
13651
+ // We do not currently support indices for memory persistence, so we can
13652
+ // return the same shared instance of the memory index manager.
13375
13653
  return this.indexManager;
13376
13654
  }
13377
- getMutationQueue(user) {
13655
+ getMutationQueue(user, indexManager) {
13378
13656
  let queue = this.mutationQueues[user.toKey()];
13379
13657
  if (!queue) {
13380
- queue = new MemoryMutationQueue(this.indexManager, this.referenceDelegate);
13658
+ queue = new MemoryMutationQueue(indexManager, this.referenceDelegate);
13381
13659
  this.mutationQueues[user.toKey()] = queue;
13382
13660
  }
13383
13661
  return queue;
@@ -20340,12 +20618,12 @@ async function syncEngineListen(syncEngine, query) {
20340
20618
  }
20341
20619
  else {
20342
20620
  const targetData = await localStoreAllocateTarget(syncEngineImpl.localStore, queryToTarget(query));
20343
- const status = syncEngineImpl.sharedClientState.addLocalQueryTarget(targetData.targetId);
20344
- targetId = targetData.targetId;
20345
- viewSnapshot = await initializeViewAndComputeSnapshot(syncEngineImpl, query, targetId, status === 'current');
20346
20621
  if (syncEngineImpl.isPrimaryClient) {
20347
20622
  remoteStoreListen(syncEngineImpl.remoteStore, targetData);
20348
20623
  }
20624
+ const status = syncEngineImpl.sharedClientState.addLocalQueryTarget(targetData.targetId);
20625
+ targetId = targetData.targetId;
20626
+ viewSnapshot = await initializeViewAndComputeSnapshot(syncEngineImpl, query, targetId, status === 'current');
20349
20627
  }
20350
20628
  return viewSnapshot;
20351
20629
  }
@@ -24853,8 +25131,7 @@ class DocumentSnapshot extends DocumentSnapshot$1 {
24853
25131
  this.metadata = metadata;
24854
25132
  }
24855
25133
  /**
24856
- * Property of the `DocumentSnapshot` that signals whether or not the data
24857
- * exists. True if the document exists.
25134
+ * Returns whether or not the data exists. True if the document exists.
24858
25135
  */
24859
25136
  exists() {
24860
25137
  return super.exists();
@@ -25228,51 +25505,53 @@ function limitToLast(limit) {
25228
25505
  return new QueryLimitConstraint('limitToLast', limit, "L" /* Last */);
25229
25506
  }
25230
25507
  class QueryStartAtConstraint extends QueryConstraint {
25231
- constructor(type, _docOrFields, _before) {
25508
+ constructor(type, _docOrFields, _inclusive) {
25232
25509
  super();
25233
25510
  this.type = type;
25234
25511
  this._docOrFields = _docOrFields;
25235
- this._before = _before;
25512
+ this._inclusive = _inclusive;
25236
25513
  }
25237
25514
  _apply(query) {
25238
- const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._before);
25515
+ const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._inclusive);
25239
25516
  return new Query(query.firestore, query.converter, queryWithStartAt(query._query, bound));
25240
25517
  }
25241
25518
  }
25242
25519
  function startAt(...docOrFields) {
25243
- return new QueryStartAtConstraint('startAt', docOrFields, /*before=*/ true);
25520
+ return new QueryStartAtConstraint('startAt', docOrFields,
25521
+ /*inclusive=*/ true);
25244
25522
  }
25245
25523
  function startAfter(...docOrFields) {
25246
25524
  return new QueryStartAtConstraint('startAfter', docOrFields,
25247
- /*before=*/ false);
25525
+ /*inclusive=*/ false);
25248
25526
  }
25249
25527
  class QueryEndAtConstraint extends QueryConstraint {
25250
- constructor(type, _docOrFields, _before) {
25528
+ constructor(type, _docOrFields, _inclusive) {
25251
25529
  super();
25252
25530
  this.type = type;
25253
25531
  this._docOrFields = _docOrFields;
25254
- this._before = _before;
25532
+ this._inclusive = _inclusive;
25255
25533
  }
25256
25534
  _apply(query) {
25257
- const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._before);
25535
+ const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._inclusive);
25258
25536
  return new Query(query.firestore, query.converter, queryWithEndAt(query._query, bound));
25259
25537
  }
25260
25538
  }
25261
25539
  function endBefore(...docOrFields) {
25262
- return new QueryEndAtConstraint('endBefore', docOrFields, /*before=*/ true);
25540
+ return new QueryEndAtConstraint('endBefore', docOrFields,
25541
+ /*inclusive=*/ false);
25263
25542
  }
25264
25543
  function endAt(...docOrFields) {
25265
- return new QueryEndAtConstraint('endAt', docOrFields, /*before=*/ false);
25544
+ return new QueryEndAtConstraint('endAt', docOrFields, /*inclusive=*/ true);
25266
25545
  }
25267
25546
  /** Helper function to create a bound from a document or fields */
25268
- function newQueryBoundFromDocOrFields(query, methodName, docOrFields, before) {
25547
+ function newQueryBoundFromDocOrFields(query, methodName, docOrFields, inclusive) {
25269
25548
  docOrFields[0] = getModularInstance(docOrFields[0]);
25270
25549
  if (docOrFields[0] instanceof DocumentSnapshot$1) {
25271
- return newQueryBoundFromDocument(query._query, query.firestore._databaseId, methodName, docOrFields[0]._document, before);
25550
+ return newQueryBoundFromDocument(query._query, query.firestore._databaseId, methodName, docOrFields[0]._document, inclusive);
25272
25551
  }
25273
25552
  else {
25274
25553
  const reader = newUserDataReader(query.firestore);
25275
- return newQueryBoundFromFields(query._query, query.firestore._databaseId, reader, methodName, docOrFields, before);
25554
+ return newQueryBoundFromFields(query._query, query.firestore._databaseId, reader, methodName, docOrFields, inclusive);
25276
25555
  }
25277
25556
  }
25278
25557
  function newQueryFilter(query, methodName, dataReader, databaseId, fieldPath, op, value) {
@@ -25330,7 +25609,7 @@ function newQueryOrderBy(query, fieldPath, direction) {
25330
25609
  * of the query or if any of the fields in the order by are an uncommitted
25331
25610
  * server timestamp.
25332
25611
  */
25333
- function newQueryBoundFromDocument(query, databaseId, methodName, doc, before) {
25612
+ function newQueryBoundFromDocument(query, databaseId, methodName, doc, inclusive) {
25334
25613
  if (!doc) {
25335
25614
  throw new FirestoreError(Code.NOT_FOUND, `Can't use a DocumentSnapshot that doesn't exist for ` +
25336
25615
  `${methodName}().`);
@@ -25367,12 +25646,12 @@ function newQueryBoundFromDocument(query, databaseId, methodName, doc, before) {
25367
25646
  }
25368
25647
  }
25369
25648
  }
25370
- return new Bound(components, before);
25649
+ return new Bound(components, inclusive);
25371
25650
  }
25372
25651
  /**
25373
25652
  * Converts a list of field values to a `Bound` for the given query.
25374
25653
  */
25375
- function newQueryBoundFromFields(query, databaseId, dataReader, methodName, values, before) {
25654
+ function newQueryBoundFromFields(query, databaseId, dataReader, methodName, values, inclusive) {
25376
25655
  // Use explicit order by's because it has to match the query the user made
25377
25656
  const orderBy = query.explicitOrderBy;
25378
25657
  if (values.length > orderBy.length) {
@@ -25409,7 +25688,7 @@ function newQueryBoundFromFields(query, databaseId, dataReader, methodName, valu
25409
25688
  components.push(wrapped);
25410
25689
  }
25411
25690
  }
25412
- return new Bound(components, before);
25691
+ return new Bound(components, inclusive);
25413
25692
  }
25414
25693
  /**
25415
25694
  * Parses the given `documentIdValue` into a `ReferenceValue`, throwing