@firebase/firestore 3.4.3 → 3.4.4-canary.0482aa5b7

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 (125) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/firestore/src/api/database.d.ts +14 -9
  3. package/dist/firestore/src/api/{query.d.ts → filter.d.ts} +0 -0
  4. package/dist/firestore/src/api/index_configuration.d.ts +117 -0
  5. package/dist/firestore/src/api/snapshot.d.ts +1 -2
  6. package/dist/firestore/src/api.d.ts +2 -1
  7. package/dist/firestore/src/core/database_info.d.ts +1 -0
  8. package/dist/firestore/src/core/firestore_client.d.ts +2 -0
  9. package/dist/firestore/src/core/target.d.ts +34 -5
  10. package/dist/firestore/src/lite-api/query.d.ts +2 -2
  11. package/dist/firestore/src/local/index_manager.d.ts +52 -0
  12. package/dist/firestore/src/local/indexeddb_index_manager.d.ts +11 -0
  13. package/dist/firestore/src/local/indexeddb_schema.d.ts +121 -7
  14. package/dist/firestore/src/local/local_serializer.d.ts +1 -1
  15. package/dist/firestore/src/local/memory_index_manager.d.ts +11 -0
  16. package/dist/firestore/src/local/remote_document_change_buffer.d.ts +3 -12
  17. package/dist/firestore/src/model/document.d.ts +7 -0
  18. package/dist/firestore/src/model/document_key.d.ts +1 -0
  19. package/dist/firestore/src/model/field_index.d.ts +156 -0
  20. package/dist/firestore/src/model/values.d.ts +7 -0
  21. package/dist/firestore/test/integration/api/index_configuration.test.d.ts +17 -0
  22. package/dist/firestore/test/unit/local/test_remote_document_cache.d.ts +1 -1
  23. package/dist/firestore/test/unit/model/field_index.test.d.ts +17 -0
  24. package/dist/firestore/test/unit/model/target.test.d.ts +17 -0
  25. package/dist/firestore/test/util/helpers.d.ts +8 -2
  26. package/dist/index.d.ts +16 -11
  27. package/dist/index.esm2017.js +2979 -2671
  28. package/dist/index.esm2017.js.map +1 -1
  29. package/dist/index.esm5.js +3036 -2815
  30. package/dist/index.esm5.js.map +1 -1
  31. package/dist/index.node.cjs.js +644 -235
  32. package/dist/index.node.cjs.js.map +1 -1
  33. package/dist/index.node.mjs +644 -236
  34. package/dist/index.node.mjs.map +1 -1
  35. package/dist/index.rn.js +2761 -2449
  36. package/dist/index.rn.js.map +1 -1
  37. package/dist/internal.d.ts +303 -25
  38. package/dist/lite/firestore/src/api/database.d.ts +14 -9
  39. package/dist/lite/firestore/src/api/{query.d.ts → filter.d.ts} +0 -0
  40. package/dist/lite/firestore/src/api/index_configuration.d.ts +117 -0
  41. package/dist/lite/firestore/src/api/snapshot.d.ts +1 -2
  42. package/dist/lite/firestore/src/api.d.ts +2 -1
  43. package/dist/lite/firestore/src/core/database_info.d.ts +1 -0
  44. package/dist/lite/firestore/src/core/firestore_client.d.ts +2 -0
  45. package/dist/lite/firestore/src/core/target.d.ts +34 -5
  46. package/dist/lite/firestore/src/lite-api/query.d.ts +2 -2
  47. package/dist/lite/firestore/src/local/index_manager.d.ts +52 -0
  48. package/dist/lite/firestore/src/local/indexeddb_index_manager.d.ts +11 -0
  49. package/dist/lite/firestore/src/local/indexeddb_schema.d.ts +121 -7
  50. package/dist/lite/firestore/src/local/local_serializer.d.ts +1 -1
  51. package/dist/lite/firestore/src/local/memory_index_manager.d.ts +11 -0
  52. package/dist/lite/firestore/src/local/remote_document_change_buffer.d.ts +3 -12
  53. package/dist/lite/firestore/src/model/document.d.ts +7 -0
  54. package/dist/lite/firestore/src/model/document_key.d.ts +1 -0
  55. package/dist/lite/firestore/src/model/field_index.d.ts +156 -0
  56. package/dist/lite/firestore/src/model/values.d.ts +7 -0
  57. package/dist/lite/firestore/test/integration/api/index_configuration.test.d.ts +17 -0
  58. package/dist/lite/firestore/test/unit/local/test_remote_document_cache.d.ts +1 -1
  59. package/dist/lite/firestore/test/unit/model/field_index.test.d.ts +17 -0
  60. package/dist/lite/firestore/test/unit/model/target.test.d.ts +17 -0
  61. package/dist/lite/firestore/test/util/helpers.d.ts +8 -2
  62. package/dist/lite/index.browser.esm2017.js +352 -338
  63. package/dist/lite/index.browser.esm2017.js.map +1 -1
  64. package/dist/lite/index.browser.esm5.js +334 -326
  65. package/dist/lite/index.browser.esm5.js.map +1 -1
  66. package/dist/lite/index.node.cjs.js +53 -34
  67. package/dist/lite/index.node.cjs.js.map +1 -1
  68. package/dist/lite/index.node.mjs +53 -34
  69. package/dist/lite/index.node.mjs.map +1 -1
  70. package/dist/lite/index.rn.esm2017.js +318 -304
  71. package/dist/lite/index.rn.esm2017.js.map +1 -1
  72. package/dist/lite/internal.d.ts +11 -2
  73. package/dist/lite/packages/firestore/dist/lite/index.browser.esm2017.d.ts +98 -97
  74. package/dist/lite/packages/firestore/src/api/database.d.ts +14 -9
  75. package/dist/lite/packages/firestore/src/api/{query.d.ts → filter.d.ts} +0 -0
  76. package/dist/lite/packages/firestore/src/api/index_configuration.d.ts +117 -0
  77. package/dist/lite/packages/firestore/src/api/snapshot.d.ts +1 -2
  78. package/dist/lite/packages/firestore/src/api.d.ts +2 -1
  79. package/dist/lite/packages/firestore/src/core/database_info.d.ts +1 -0
  80. package/dist/lite/packages/firestore/src/core/firestore_client.d.ts +2 -0
  81. package/dist/lite/packages/firestore/src/core/target.d.ts +34 -5
  82. package/dist/lite/packages/firestore/src/lite-api/query.d.ts +2 -2
  83. package/dist/lite/packages/firestore/src/local/index_manager.d.ts +52 -0
  84. package/dist/lite/packages/firestore/src/local/indexeddb_index_manager.d.ts +11 -0
  85. package/dist/lite/packages/firestore/src/local/indexeddb_schema.d.ts +121 -7
  86. package/dist/lite/packages/firestore/src/local/local_serializer.d.ts +1 -1
  87. package/dist/lite/packages/firestore/src/local/memory_index_manager.d.ts +11 -0
  88. package/dist/lite/packages/firestore/src/local/remote_document_change_buffer.d.ts +3 -12
  89. package/dist/lite/packages/firestore/src/model/document.d.ts +7 -0
  90. package/dist/lite/packages/firestore/src/model/document_key.d.ts +1 -0
  91. package/dist/lite/packages/firestore/src/model/field_index.d.ts +156 -0
  92. package/dist/lite/packages/firestore/src/model/values.d.ts +7 -0
  93. package/dist/lite/packages/firestore/test/integration/api/index_configuration.test.d.ts +17 -0
  94. package/dist/lite/packages/firestore/test/unit/local/test_remote_document_cache.d.ts +1 -1
  95. package/dist/lite/packages/firestore/test/unit/model/field_index.test.d.ts +17 -0
  96. package/dist/lite/packages/firestore/test/unit/model/target.test.d.ts +17 -0
  97. package/dist/lite/packages/firestore/test/util/helpers.d.ts +8 -2
  98. package/dist/lite/private.d.ts +9 -2
  99. package/dist/packages/firestore/dist/index.esm2017.d.ts +214 -191
  100. package/dist/packages/firestore/src/api/database.d.ts +14 -9
  101. package/dist/packages/firestore/src/api/{query.d.ts → filter.d.ts} +0 -0
  102. package/dist/packages/firestore/src/api/index_configuration.d.ts +117 -0
  103. package/dist/packages/firestore/src/api/snapshot.d.ts +1 -2
  104. package/dist/packages/firestore/src/api.d.ts +2 -1
  105. package/dist/packages/firestore/src/core/database_info.d.ts +1 -0
  106. package/dist/packages/firestore/src/core/firestore_client.d.ts +2 -0
  107. package/dist/packages/firestore/src/core/target.d.ts +34 -5
  108. package/dist/packages/firestore/src/lite-api/query.d.ts +2 -2
  109. package/dist/packages/firestore/src/local/index_manager.d.ts +52 -0
  110. package/dist/packages/firestore/src/local/indexeddb_index_manager.d.ts +11 -0
  111. package/dist/packages/firestore/src/local/indexeddb_schema.d.ts +121 -7
  112. package/dist/packages/firestore/src/local/local_serializer.d.ts +1 -1
  113. package/dist/packages/firestore/src/local/memory_index_manager.d.ts +11 -0
  114. package/dist/packages/firestore/src/local/remote_document_change_buffer.d.ts +3 -12
  115. package/dist/packages/firestore/src/model/document.d.ts +7 -0
  116. package/dist/packages/firestore/src/model/document_key.d.ts +1 -0
  117. package/dist/packages/firestore/src/model/field_index.d.ts +156 -0
  118. package/dist/packages/firestore/src/model/values.d.ts +7 -0
  119. package/dist/packages/firestore/test/integration/api/index_configuration.test.d.ts +17 -0
  120. package/dist/packages/firestore/test/unit/local/test_remote_document_cache.d.ts +1 -1
  121. package/dist/packages/firestore/test/unit/model/field_index.test.d.ts +17 -0
  122. package/dist/packages/firestore/test/unit/model/target.test.d.ts +17 -0
  123. package/dist/packages/firestore/test/util/helpers.d.ts +8 -2
  124. package/dist/private.d.ts +205 -25
  125. package/package.json +10 -10
@@ -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.3";
11
+ const version$1 = "3.4.4-canary.0482aa5b7";
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.3";
64
+ const version = "9.6.5-canary.0482aa5b7";
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,93 @@ 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
+ /** The index id for this entry. */
1778
+ indexId,
1779
+ /** The collection group this index belongs to. */
1780
+ collectionGroup,
1781
+ /** The fields to index for this index. */
1782
+ fields) {
1783
+ this.indexId = indexId;
1784
+ this.collectionGroup = collectionGroup;
1785
+ this.fields = fields;
1786
+ }
1787
+ }
1788
+ /** Name of the IndexedDb object store. */
1789
+ DbIndexConfiguration.store = 'indexConfiguration';
1790
+ DbIndexConfiguration.keyPath = 'indexId';
1791
+ /**
1792
+ * An object describing how up-to-date the index backfill is for each user and
1793
+ * index.
1794
+ */
1795
+ class DbIndexState {
1796
+ constructor(
1797
+ /** The index id for this entry. */
1798
+ indexId,
1799
+ /** The user id for this entry. */
1800
+ uid,
1801
+ /**
1802
+ * A number that indicates when the index was last updated (relative to
1803
+ * other indexes).
1804
+ */
1805
+ sequenceNumber,
1806
+ /**
1807
+ * The latest read time that has been indexed by Firestore for this field
1808
+ * index. Set to `{seconds: 0, nanos: 0}` if no documents have been indexed.
1809
+ */
1810
+ readTime,
1811
+ /**
1812
+ * The last document that has been indexed for this field index. Empty if
1813
+ * no documents have been indexed.
1814
+ */
1815
+ documentKey,
1816
+ /**
1817
+ * The largest mutation batch id that has been processed for this index. -1
1818
+ * if no mutations have been indexed.
1819
+ */
1820
+ largestBatchId) {
1821
+ this.indexId = indexId;
1822
+ this.uid = uid;
1823
+ this.sequenceNumber = sequenceNumber;
1824
+ this.readTime = readTime;
1825
+ this.documentKey = documentKey;
1826
+ this.largestBatchId = largestBatchId;
1827
+ }
1828
+ }
1829
+ /** Name of the IndexedDb object store. */
1830
+ DbIndexState.store = 'indexState';
1831
+ DbIndexState.keyPath = ['indexId', 'uid'];
1832
+ /** An object that stores the encoded entries for all documents and fields. */
1833
+ class DbIndexEntries {
1834
+ constructor(
1835
+ /** The index id for this entry. */
1836
+ indexId,
1837
+ /** The user id for this entry. */
1838
+ uid,
1839
+ /** The encoded array index value for this entry. */
1840
+ arrayValue,
1841
+ /** The encoded directional value for equality and inequality filters. */
1842
+ directionalValue,
1843
+ /** The document key this entry points to. */
1844
+ documentKey) {
1845
+ this.indexId = indexId;
1846
+ this.uid = uid;
1847
+ this.arrayValue = arrayValue;
1848
+ this.directionalValue = directionalValue;
1849
+ this.documentKey = documentKey;
1850
+ }
1851
+ }
1852
+ /** Name of the IndexedDb object store. */
1853
+ DbIndexEntries.store = 'indexEntries';
1854
+ DbIndexEntries.keyPath = [
1855
+ 'indexId',
1856
+ 'uid',
1857
+ 'arrayValue',
1858
+ 'directionalValue',
1859
+ 'documentKey'
1860
+ ];
1794
1861
  // Visible for testing
1795
1862
  const V1_STORES = [
1796
1863
  DbMutationQueue.store,
@@ -1805,7 +1872,6 @@ const V1_STORES = [
1805
1872
  // V2 is no longer usable (see comment at top of file)
1806
1873
  // Visible for testing
1807
1874
  const V3_STORES = V1_STORES;
1808
- // Visible for testing
1809
1875
  // Note: DbRemoteDocumentChanges is no longer used and dropped with v9.
1810
1876
  const V4_STORES = [...V3_STORES, DbClientMetadata.store];
1811
1877
  // V5 does not change the set of stores.
@@ -1815,6 +1881,12 @@ const V8_STORES = [...V6_STORES, DbCollectionParent.store];
1815
1881
  // V9 does not change the set of stores.
1816
1882
  // V10 does not change the set of stores.
1817
1883
  const V11_STORES = [...V8_STORES, DbBundle.store, DbNamedQuery.store];
1884
+ [
1885
+ ...V11_STORES,
1886
+ DbIndexConfiguration.store,
1887
+ DbIndexState.store,
1888
+ DbIndexEntries.store
1889
+ ];
1818
1890
  /**
1819
1891
  * The list of all default IndexedDB stores used throughout the SDK. This is
1820
1892
  * used when creating transactions so that access across all stores is done
@@ -3374,6 +3446,75 @@ function getLocalWriteTime(value) {
3374
3446
  return new Timestamp(localWriteTime.seconds, localWriteTime.nanos);
3375
3447
  }
3376
3448
 
3449
+ /**
3450
+ * @license
3451
+ * Copyright 2017 Google LLC
3452
+ *
3453
+ * Licensed under the Apache License, Version 2.0 (the "License");
3454
+ * you may not use this file except in compliance with the License.
3455
+ * You may obtain a copy of the License at
3456
+ *
3457
+ * http://www.apache.org/licenses/LICENSE-2.0
3458
+ *
3459
+ * Unless required by applicable law or agreed to in writing, software
3460
+ * distributed under the License is distributed on an "AS IS" BASIS,
3461
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3462
+ * See the License for the specific language governing permissions and
3463
+ * limitations under the License.
3464
+ */
3465
+ class DatabaseInfo {
3466
+ /**
3467
+ * Constructs a DatabaseInfo using the provided host, databaseId and
3468
+ * persistenceKey.
3469
+ *
3470
+ * @param databaseId - The database to use.
3471
+ * @param appId - The Firebase App Id.
3472
+ * @param persistenceKey - A unique identifier for this Firestore's local
3473
+ * storage (used in conjunction with the databaseId).
3474
+ * @param host - The Firestore backend host to connect to.
3475
+ * @param ssl - Whether to use SSL when connecting.
3476
+ * @param forceLongPolling - Whether to use the forceLongPolling option
3477
+ * when using WebChannel as the network transport.
3478
+ * @param autoDetectLongPolling - Whether to use the detectBufferingProxy
3479
+ * option when using WebChannel as the network transport.
3480
+ * @param useFetchStreams Whether to use the Fetch API instead of
3481
+ * XMLHTTPRequest
3482
+ */
3483
+ constructor(databaseId, appId, persistenceKey, host, ssl, forceLongPolling, autoDetectLongPolling, useFetchStreams) {
3484
+ this.databaseId = databaseId;
3485
+ this.appId = appId;
3486
+ this.persistenceKey = persistenceKey;
3487
+ this.host = host;
3488
+ this.ssl = ssl;
3489
+ this.forceLongPolling = forceLongPolling;
3490
+ this.autoDetectLongPolling = autoDetectLongPolling;
3491
+ this.useFetchStreams = useFetchStreams;
3492
+ }
3493
+ }
3494
+ /** The default database name for a project. */
3495
+ const DEFAULT_DATABASE_NAME = '(default)';
3496
+ /**
3497
+ * Represents the database ID a Firestore client is associated with.
3498
+ * @internal
3499
+ */
3500
+ class DatabaseId {
3501
+ constructor(projectId, database) {
3502
+ this.projectId = projectId;
3503
+ this.database = database ? database : DEFAULT_DATABASE_NAME;
3504
+ }
3505
+ static empty() {
3506
+ return new DatabaseId('', '');
3507
+ }
3508
+ get isDefaultDatabase() {
3509
+ return this.database === DEFAULT_DATABASE_NAME;
3510
+ }
3511
+ isEqual(other) {
3512
+ return (other instanceof DatabaseId &&
3513
+ other.projectId === this.projectId &&
3514
+ other.database === this.database);
3515
+ }
3516
+ }
3517
+
3377
3518
  /**
3378
3519
  * @license
3379
3520
  * Copyright 2017 Google LLC
@@ -3445,6 +3586,9 @@ class DocumentKey {
3445
3586
  static fromName(name) {
3446
3587
  return new DocumentKey(ResourcePath.fromString(name).popFirst(5));
3447
3588
  }
3589
+ static empty() {
3590
+ return new DocumentKey(ResourcePath.emptyPath());
3591
+ }
3448
3592
  /** Returns true if the document is in the specified collectionId. */
3449
3593
  hasCollectionId(collectionId) {
3450
3594
  return (this.path.length >= 2 &&
@@ -4093,10 +4237,11 @@ function extractFieldMask(value) {
4093
4237
  * from all views.
4094
4238
  */
4095
4239
  class MutableDocument {
4096
- constructor(key, documentType, version, data, documentState) {
4240
+ constructor(key, documentType, version, readTime, data, documentState) {
4097
4241
  this.key = key;
4098
4242
  this.documentType = documentType;
4099
4243
  this.version = version;
4244
+ this.readTime = readTime;
4100
4245
  this.data = data;
4101
4246
  this.documentState = documentState;
4102
4247
  }
@@ -4105,18 +4250,18 @@ class MutableDocument {
4105
4250
  * base document for mutations.
4106
4251
  */
4107
4252
  static newInvalidDocument(documentKey) {
4108
- return new MutableDocument(documentKey, 0 /* INVALID */, SnapshotVersion.min(), ObjectValue.empty(), 0 /* SYNCED */);
4253
+ return new MutableDocument(documentKey, 0 /* INVALID */, SnapshotVersion.min(), SnapshotVersion.min(), ObjectValue.empty(), 0 /* SYNCED */);
4109
4254
  }
4110
4255
  /**
4111
4256
  * Creates a new document that is known to exist with the given data at the
4112
4257
  * given version.
4113
4258
  */
4114
4259
  static newFoundDocument(documentKey, version, value) {
4115
- return new MutableDocument(documentKey, 1 /* FOUND_DOCUMENT */, version, value, 0 /* SYNCED */);
4260
+ return new MutableDocument(documentKey, 1 /* FOUND_DOCUMENT */, version, SnapshotVersion.min(), value, 0 /* SYNCED */);
4116
4261
  }
4117
4262
  /** Creates a new document that is known to not exist at the given version. */
4118
4263
  static newNoDocument(documentKey, version) {
4119
- return new MutableDocument(documentKey, 2 /* NO_DOCUMENT */, version, ObjectValue.empty(), 0 /* SYNCED */);
4264
+ return new MutableDocument(documentKey, 2 /* NO_DOCUMENT */, version, SnapshotVersion.min(), ObjectValue.empty(), 0 /* SYNCED */);
4120
4265
  }
4121
4266
  /**
4122
4267
  * Creates a new document that is known to exist at the given version but
@@ -4124,7 +4269,7 @@ class MutableDocument {
4124
4269
  * base document).
4125
4270
  */
4126
4271
  static newUnknownDocument(documentKey, version) {
4127
- return new MutableDocument(documentKey, 3 /* UNKNOWN_DOCUMENT */, version, ObjectValue.empty(), 2 /* HAS_COMMITTED_MUTATIONS */);
4272
+ return new MutableDocument(documentKey, 3 /* UNKNOWN_DOCUMENT */, version, SnapshotVersion.min(), ObjectValue.empty(), 2 /* HAS_COMMITTED_MUTATIONS */);
4128
4273
  }
4129
4274
  /**
4130
4275
  * Changes the document type to indicate that it exists and that its version
@@ -4168,6 +4313,10 @@ class MutableDocument {
4168
4313
  this.documentState = 1 /* HAS_LOCAL_MUTATIONS */;
4169
4314
  return this;
4170
4315
  }
4316
+ setReadTime(readTime) {
4317
+ this.readTime = readTime;
4318
+ return this;
4319
+ }
4171
4320
  get hasLocalMutations() {
4172
4321
  return this.documentState === 1 /* HAS_LOCAL_MUTATIONS */;
4173
4322
  }
@@ -4198,7 +4347,7 @@ class MutableDocument {
4198
4347
  this.data.isEqual(other.data));
4199
4348
  }
4200
4349
  mutableCopy() {
4201
- return new MutableDocument(this.key, this.documentType, this.version, this.data.clone(), this.documentState);
4350
+ return new MutableDocument(this.key, this.documentType, this.version, this.readTime, this.data.clone(), this.documentState);
4202
4351
  }
4203
4352
  toString() {
4204
4353
  return (`Document(${this.key}, ${this.version}, ${JSON.stringify(this.data.value)}, ` +
@@ -4221,6 +4370,125 @@ function compareDocumentsByField(field, d1, d2) {
4221
4370
  }
4222
4371
  }
4223
4372
 
4373
+ /**
4374
+ * @license
4375
+ * Copyright 2021 Google LLC
4376
+ *
4377
+ * Licensed under the Apache License, Version 2.0 (the "License");
4378
+ * you may not use this file except in compliance with the License.
4379
+ * You may obtain a copy of the License at
4380
+ *
4381
+ * http://www.apache.org/licenses/LICENSE-2.0
4382
+ *
4383
+ * Unless required by applicable law or agreed to in writing, software
4384
+ * distributed under the License is distributed on an "AS IS" BASIS,
4385
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4386
+ * See the License for the specific language governing permissions and
4387
+ * limitations under the License.
4388
+ */
4389
+ /**
4390
+ * The initial mutation batch id for each index. Gets updated during index
4391
+ * backfill.
4392
+ */
4393
+ const INITIAL_LARGEST_BATCH_ID = -1;
4394
+ /**
4395
+ * The initial sequence number for each index. Gets updated during index
4396
+ * backfill.
4397
+ */
4398
+ const INITIAL_SEQUENCE_NUMBER = 0;
4399
+ /**
4400
+ * An index definition for field indexes in Firestore.
4401
+ *
4402
+ * Every index is associated with a collection. The definition contains a list
4403
+ * of fields and their index kind (which can be `ASCENDING`, `DESCENDING` or
4404
+ * `CONTAINS` for ArrayContains/ArrayContainsAny queries).
4405
+ *
4406
+ * Unlike the backend, the SDK does not differentiate between collection or
4407
+ * collection group-scoped indices. Every index can be used for both single
4408
+ * collection and collection group queries.
4409
+ */
4410
+ class FieldIndex {
4411
+ constructor(
4412
+ /**
4413
+ * The index ID. Returns -1 if the index ID is not available (e.g. the index
4414
+ * has not yet been persisted).
4415
+ */
4416
+ indexId,
4417
+ /** The collection ID this index applies to. */
4418
+ collectionGroup,
4419
+ /** The field segments for this index. */
4420
+ segments,
4421
+ /** Shows how up-to-date the index is for the current user. */
4422
+ indexState) {
4423
+ this.indexId = indexId;
4424
+ this.collectionGroup = collectionGroup;
4425
+ this.segments = segments;
4426
+ this.indexState = indexState;
4427
+ }
4428
+ }
4429
+ /** An ID for an index that has not yet been added to persistence. */
4430
+ FieldIndex.UNKNOWN_ID = -1;
4431
+ /** An index component consisting of field path and index type. */
4432
+ class IndexSegment {
4433
+ constructor(
4434
+ /** The field path of the component. */
4435
+ fieldPath,
4436
+ /** The fields sorting order. */
4437
+ kind) {
4438
+ this.fieldPath = fieldPath;
4439
+ this.kind = kind;
4440
+ }
4441
+ }
4442
+ /**
4443
+ * Stores the "high water mark" that indicates how updated the Index is for the
4444
+ * current user.
4445
+ */
4446
+ class IndexState {
4447
+ constructor(
4448
+ /**
4449
+ * Indicates when the index was last updated (relative to other indexes).
4450
+ */
4451
+ sequenceNumber,
4452
+ /** The the latest indexed read time, document and batch id. */
4453
+ offset) {
4454
+ this.sequenceNumber = sequenceNumber;
4455
+ this.offset = offset;
4456
+ }
4457
+ /** The state of an index that has not yet been backfilled. */
4458
+ static empty() {
4459
+ return new IndexState(INITIAL_SEQUENCE_NUMBER, IndexOffset.min());
4460
+ }
4461
+ }
4462
+ /**
4463
+ * Stores the latest read time, document and batch ID that were processed for an
4464
+ * index.
4465
+ */
4466
+ class IndexOffset {
4467
+ constructor(
4468
+ /**
4469
+ * The latest read time version that has been indexed by Firestore for this
4470
+ * field index.
4471
+ */
4472
+ readTime,
4473
+ /**
4474
+ * The key of the last document that was indexed for this query. Use
4475
+ * `DocumentKey.empty()` if no document has been indexed.
4476
+ */
4477
+ documentKey,
4478
+ /*
4479
+ * The largest mutation batch id that's been processed by Firestore.
4480
+ */
4481
+ largestBatchId) {
4482
+ this.readTime = readTime;
4483
+ this.documentKey = documentKey;
4484
+ this.largestBatchId = largestBatchId;
4485
+ }
4486
+ /** The state of an index that has not yet been backfilled. */
4487
+ static min() {
4488
+ return new IndexOffset(SnapshotVersion.min(), DocumentKey.empty(), INITIAL_LARGEST_BATCH_ID);
4489
+ }
4490
+ }
4491
+
4224
4492
  /**
4225
4493
  * @license
4226
4494
  * Copyright 2019 Google LLC
@@ -4264,27 +4532,29 @@ function newTarget(path, collectionGroup = null, orderBy = [], filters = [], lim
4264
4532
  function canonifyTarget(target) {
4265
4533
  const targetImpl = debugCast(target);
4266
4534
  if (targetImpl.memoizedCanonicalId === null) {
4267
- let canonicalId = targetImpl.path.canonicalString();
4535
+ let str = targetImpl.path.canonicalString();
4268
4536
  if (targetImpl.collectionGroup !== null) {
4269
- canonicalId += '|cg:' + targetImpl.collectionGroup;
4537
+ str += '|cg:' + targetImpl.collectionGroup;
4270
4538
  }
4271
- canonicalId += '|f:';
4272
- canonicalId += targetImpl.filters.map(f => canonifyFilter(f)).join(',');
4273
- canonicalId += '|ob:';
4274
- canonicalId += targetImpl.orderBy.map(o => canonifyOrderBy(o)).join(',');
4539
+ str += '|f:';
4540
+ str += targetImpl.filters.map(f => canonifyFilter(f)).join(',');
4541
+ str += '|ob:';
4542
+ str += targetImpl.orderBy.map(o => canonifyOrderBy(o)).join(',');
4275
4543
  if (!isNullOrUndefined(targetImpl.limit)) {
4276
- canonicalId += '|l:';
4277
- canonicalId += targetImpl.limit;
4544
+ str += '|l:';
4545
+ str += targetImpl.limit;
4278
4546
  }
4279
4547
  if (targetImpl.startAt) {
4280
- canonicalId += '|lb:';
4281
- canonicalId += canonifyBound(targetImpl.startAt);
4548
+ str += '|lb:';
4549
+ str += targetImpl.startAt.inclusive ? 'b:' : 'a:';
4550
+ str += targetImpl.startAt.position.map(p => canonicalId(p)).join(',');
4282
4551
  }
4283
4552
  if (targetImpl.endAt) {
4284
- canonicalId += '|ub:';
4285
- canonicalId += canonifyBound(targetImpl.endAt);
4553
+ str += '|ub:';
4554
+ str += targetImpl.endAt.inclusive ? 'a:' : 'b:';
4555
+ str += targetImpl.endAt.position.map(p => canonicalId(p)).join(',');
4286
4556
  }
4287
- targetImpl.memoizedCanonicalId = canonicalId;
4557
+ targetImpl.memoizedCanonicalId = str;
4288
4558
  }
4289
4559
  return targetImpl.memoizedCanonicalId;
4290
4560
  }
@@ -4307,10 +4577,14 @@ function stringifyTarget(target) {
4307
4577
  .join(', ')}]`;
4308
4578
  }
4309
4579
  if (target.startAt) {
4310
- str += ', startAt: ' + canonifyBound(target.startAt);
4580
+ str += ', startAt: ';
4581
+ str += target.startAt.inclusive ? 'b:' : 'a:';
4582
+ str += target.startAt.position.map(p => canonicalId(p)).join(',');
4311
4583
  }
4312
4584
  if (target.endAt) {
4313
- str += ', endAt: ' + canonifyBound(target.endAt);
4585
+ str += ', endAt: ';
4586
+ str += target.endAt.inclusive ? 'a:' : 'b:';
4587
+ str += target.endAt.position.map(p => canonicalId(p)).join(',');
4314
4588
  }
4315
4589
  return `Target(${str})`;
4316
4590
  }
@@ -4345,7 +4619,7 @@ function targetEquals(left, right) {
4345
4619
  }
4346
4620
  return boundEquals(left.endAt, right.endAt);
4347
4621
  }
4348
- function isDocumentTarget(target) {
4622
+ function targetIsDocumentTarget(target) {
4349
4623
  return (DocumentKey.isDocumentKey(target.path) &&
4350
4624
  target.collectionGroup === null &&
4351
4625
  target.filters.length === 0);
@@ -4548,17 +4822,11 @@ class ArrayContainsAnyFilter extends FieldFilter {
4548
4822
  * just after the provided values.
4549
4823
  */
4550
4824
  class Bound {
4551
- constructor(position, before) {
4825
+ constructor(position, inclusive) {
4552
4826
  this.position = position;
4553
- this.before = before;
4827
+ this.inclusive = inclusive;
4554
4828
  }
4555
4829
  }
4556
- function canonifyBound(bound) {
4557
- // TODO(b/29183165): Make this collision robust.
4558
- return `${bound.before ? 'b' : 'a'}:${bound.position
4559
- .map(p => canonicalId(p))
4560
- .join(',')}`;
4561
- }
4562
4830
  /**
4563
4831
  * An ordering on a field, in some Direction. Direction defaults to ASCENDING.
4564
4832
  */
@@ -4578,11 +4846,7 @@ function stringifyOrderBy(orderBy) {
4578
4846
  function orderByEquals(left, right) {
4579
4847
  return left.dir === right.dir && left.field.isEqual(right.field);
4580
4848
  }
4581
- /**
4582
- * Returns true if a document sorts before a bound using the provided sort
4583
- * order.
4584
- */
4585
- function sortsBeforeDocument(bound, orderBy, doc) {
4849
+ function boundCompareToDocument(bound, orderBy, doc) {
4586
4850
  let comparison = 0;
4587
4851
  for (let i = 0; i < bound.position.length; i++) {
4588
4852
  const orderByComponent = orderBy[i];
@@ -4601,7 +4865,23 @@ function sortsBeforeDocument(bound, orderBy, doc) {
4601
4865
  break;
4602
4866
  }
4603
4867
  }
4604
- return bound.before ? comparison <= 0 : comparison < 0;
4868
+ return comparison;
4869
+ }
4870
+ /**
4871
+ * Returns true if a document sorts after a bound using the provided sort
4872
+ * order.
4873
+ */
4874
+ function boundSortsAfterDocument(bound, orderBy, doc) {
4875
+ const comparison = boundCompareToDocument(bound, orderBy, doc);
4876
+ return bound.inclusive ? comparison >= 0 : comparison > 0;
4877
+ }
4878
+ /**
4879
+ * Returns true if a document sorts before a bound using the provided sort
4880
+ * order.
4881
+ */
4882
+ function boundSortsBeforeDocument(bound, orderBy, doc) {
4883
+ const comparison = boundCompareToDocument(bound, orderBy, doc);
4884
+ return bound.inclusive ? comparison <= 0 : comparison < 0;
4605
4885
  }
4606
4886
  function boundEquals(left, right) {
4607
4887
  if (left === null) {
@@ -4610,7 +4890,7 @@ function boundEquals(left, right) {
4610
4890
  else if (right === null) {
4611
4891
  return false;
4612
4892
  }
4613
- if (left.before !== right.before ||
4893
+ if (left.inclusive !== right.inclusive ||
4614
4894
  left.position.length !== right.position.length) {
4615
4895
  return false;
4616
4896
  }
@@ -4814,10 +5094,10 @@ function queryToTarget(query) {
4814
5094
  }
4815
5095
  // We need to swap the cursors to match the now-flipped query ordering.
4816
5096
  const startAt = queryImpl.endAt
4817
- ? new Bound(queryImpl.endAt.position, !queryImpl.endAt.before)
5097
+ ? new Bound(queryImpl.endAt.position, !queryImpl.endAt.inclusive)
4818
5098
  : null;
4819
5099
  const endAt = queryImpl.startAt
4820
- ? new Bound(queryImpl.startAt.position, !queryImpl.startAt.before)
5100
+ ? new Bound(queryImpl.startAt.position, !queryImpl.startAt.inclusive)
4821
5101
  : null;
4822
5102
  // Now return as a LimitType.First query.
4823
5103
  queryImpl.memoizedTarget = newTarget(queryImpl.path, queryImpl.collectionGroup, orderBys, queryImpl.filters, queryImpl.limit, startAt, endAt);
@@ -4905,11 +5185,11 @@ function queryMatchesFilters(query, doc) {
4905
5185
  /** Makes sure a document is within the bounds, if provided. */
4906
5186
  function queryMatchesBounds(query, doc) {
4907
5187
  if (query.startAt &&
4908
- !sortsBeforeDocument(query.startAt, queryOrderBy(query), doc)) {
5188
+ !boundSortsBeforeDocument(query.startAt, queryOrderBy(query), doc)) {
4909
5189
  return false;
4910
5190
  }
4911
5191
  if (query.endAt &&
4912
- sortsBeforeDocument(query.endAt, queryOrderBy(query), doc)) {
5192
+ !boundSortsAfterDocument(query.endAt, queryOrderBy(query), doc)) {
4913
5193
  return false;
4914
5194
  }
4915
5195
  return true;
@@ -6990,7 +7270,7 @@ class WatchChangeAggregator {
6990
7270
  const targetData = this.targetDataForActiveTarget(targetId);
6991
7271
  if (targetData) {
6992
7272
  const target = targetData.target;
6993
- if (isDocumentTarget(target)) {
7273
+ if (targetIsDocumentTarget(target)) {
6994
7274
  if (expectedCount === 0) {
6995
7275
  // The existence filter told us the document does not exist. We deduce
6996
7276
  // that this document does not exist and apply a deleted document to
@@ -7025,7 +7305,7 @@ class WatchChangeAggregator {
7025
7305
  this.targetStates.forEach((targetState, targetId) => {
7026
7306
  const targetData = this.targetDataForActiveTarget(targetId);
7027
7307
  if (targetData) {
7028
- if (targetState.current && isDocumentTarget(targetData.target)) {
7308
+ if (targetState.current && targetIsDocumentTarget(targetData.target)) {
7029
7309
  // Document queries for document that don't exist can produce an empty
7030
7310
  // result set. To update our local cache, we synthesize a document
7031
7311
  // delete if we have not previously received the document. This
@@ -7068,6 +7348,7 @@ class WatchChangeAggregator {
7068
7348
  resolvedLimboDocuments = resolvedLimboDocuments.add(key);
7069
7349
  }
7070
7350
  });
7351
+ this.pendingDocumentUpdates.forEach((_, doc) => doc.setReadTime(snapshotVersion));
7071
7352
  const remoteEvent = new RemoteEvent(snapshotVersion, targetChanges, this.pendingTargetResets, this.pendingDocumentUpdates, resolvedLimboDocuments);
7072
7353
  this.pendingDocumentUpdates = mutableDocumentMap();
7073
7354
  this.pendingDocumentTargetMapping = documentTargetMap();
@@ -7787,10 +8068,10 @@ function toQueryTarget(serializer, target) {
7787
8068
  result.structuredQuery.limit = limit;
7788
8069
  }
7789
8070
  if (target.startAt) {
7790
- result.structuredQuery.startAt = toCursor(target.startAt);
8071
+ result.structuredQuery.startAt = toStartAtCursor(target.startAt);
7791
8072
  }
7792
8073
  if (target.endAt) {
7793
- result.structuredQuery.endAt = toCursor(target.endAt);
8074
+ result.structuredQuery.endAt = toEndAtCursor(target.endAt);
7794
8075
  }
7795
8076
  return result;
7796
8077
  }
@@ -7823,11 +8104,11 @@ function convertQueryTargetToQuery(target) {
7823
8104
  }
7824
8105
  let startAt = null;
7825
8106
  if (query.startAt) {
7826
- startAt = fromCursor(query.startAt);
8107
+ startAt = fromStartAtCursor(query.startAt);
7827
8108
  }
7828
8109
  let endAt = null;
7829
8110
  if (query.endAt) {
7830
- endAt = fromCursor(query.endAt);
8111
+ endAt = fromEndAtCursor(query.endAt);
7831
8112
  }
7832
8113
  return newQuery(path, collectionGroup, orderBy, filterBy, limit, "F" /* First */, startAt, endAt);
7833
8114
  }
@@ -7860,7 +8141,7 @@ function toLabel(serializer, purpose) {
7860
8141
  function toTarget(serializer, targetData) {
7861
8142
  let result;
7862
8143
  const target = targetData.target;
7863
- if (isDocumentTarget(target)) {
8144
+ if (targetIsDocumentTarget(target)) {
7864
8145
  result = { documents: toDocumentsTarget(serializer, target) };
7865
8146
  }
7866
8147
  else {
@@ -7918,16 +8199,27 @@ function toOrder(orderBys) {
7918
8199
  function fromOrder(orderBys) {
7919
8200
  return orderBys.map(order => fromPropertyOrder(order));
7920
8201
  }
7921
- function toCursor(cursor) {
8202
+ function toStartAtCursor(cursor) {
8203
+ return {
8204
+ before: cursor.inclusive,
8205
+ values: cursor.position
8206
+ };
8207
+ }
8208
+ function toEndAtCursor(cursor) {
7922
8209
  return {
7923
- before: cursor.before,
8210
+ before: !cursor.inclusive,
7924
8211
  values: cursor.position
7925
8212
  };
7926
8213
  }
7927
- function fromCursor(cursor) {
7928
- const before = !!cursor.before;
8214
+ function fromStartAtCursor(cursor) {
8215
+ const inclusive = !!cursor.before;
7929
8216
  const position = cursor.values || [];
7930
- return new Bound(position, before);
8217
+ return new Bound(position, inclusive);
8218
+ }
8219
+ function fromEndAtCursor(cursor) {
8220
+ const inclusive = !cursor.before;
8221
+ const position = cursor.values || [];
8222
+ return new Bound(position, inclusive);
7931
8223
  }
7932
8224
  // visible for testing
7933
8225
  function toDirection(dir) {
@@ -8188,29 +8480,34 @@ class LocalSerializer {
8188
8480
  }
8189
8481
  /** Decodes a remote document from storage locally to a Document. */
8190
8482
  function fromDbRemoteDocument(localSerializer, remoteDoc) {
8483
+ let doc;
8191
8484
  if (remoteDoc.document) {
8192
- return fromDocument(localSerializer.remoteSerializer, remoteDoc.document, !!remoteDoc.hasCommittedMutations);
8485
+ doc = fromDocument(localSerializer.remoteSerializer, remoteDoc.document, !!remoteDoc.hasCommittedMutations);
8193
8486
  }
8194
8487
  else if (remoteDoc.noDocument) {
8195
8488
  const key = DocumentKey.fromSegments(remoteDoc.noDocument.path);
8196
8489
  const version = fromDbTimestamp(remoteDoc.noDocument.readTime);
8197
- const document = MutableDocument.newNoDocument(key, version);
8198
- return remoteDoc.hasCommittedMutations
8199
- ? document.setHasCommittedMutations()
8200
- : document;
8490
+ doc = MutableDocument.newNoDocument(key, version);
8491
+ if (remoteDoc.hasCommittedMutations) {
8492
+ doc.setHasCommittedMutations();
8493
+ }
8201
8494
  }
8202
8495
  else if (remoteDoc.unknownDocument) {
8203
8496
  const key = DocumentKey.fromSegments(remoteDoc.unknownDocument.path);
8204
8497
  const version = fromDbTimestamp(remoteDoc.unknownDocument.version);
8205
- return MutableDocument.newUnknownDocument(key, version);
8498
+ doc = MutableDocument.newUnknownDocument(key, version);
8206
8499
  }
8207
8500
  else {
8208
8501
  return fail();
8209
8502
  }
8503
+ if (remoteDoc.readTime) {
8504
+ doc.setReadTime(fromDbTimestampKey(remoteDoc.readTime));
8505
+ }
8506
+ return doc;
8210
8507
  }
8211
8508
  /** Encodes a document for storage locally. */
8212
- function toDbRemoteDocument(localSerializer, document, readTime) {
8213
- const dbReadTime = toDbTimestampKey(readTime);
8509
+ function toDbRemoteDocument(localSerializer, document) {
8510
+ const dbReadTime = toDbTimestampKey(document.readTime);
8214
8511
  const parentPath = document.key.path.popLast().toArray();
8215
8512
  if (document.isFoundDocument()) {
8216
8513
  const doc = toDocument(localSerializer.remoteSerializer, document);
@@ -8221,10 +8518,10 @@ function toDbRemoteDocument(localSerializer, document, readTime) {
8221
8518
  }
8222
8519
  else if (document.isNoDocument()) {
8223
8520
  const path = document.key.path.toArray();
8224
- const readTime = toDbTimestamp(document.version);
8521
+ const version = toDbTimestamp(document.version);
8225
8522
  const hasCommittedMutations = document.hasCommittedMutations;
8226
8523
  return new DbRemoteDocument(
8227
- /* unknownDocument= */ null, new DbNoDocument(path, readTime),
8524
+ /* unknownDocument= */ null, new DbNoDocument(path, version),
8228
8525
  /* document= */ null, hasCommittedMutations, dbReadTime, parentPath);
8229
8526
  }
8230
8527
  else if (document.isUnknownDocument()) {
@@ -8305,7 +8602,7 @@ function toDbTarget(localSerializer, targetData) {
8305
8602
  const dbTimestamp = toDbTimestamp(targetData.snapshotVersion);
8306
8603
  const dbLastLimboFreeTimestamp = toDbTimestamp(targetData.lastLimboFreeSnapshotVersion);
8307
8604
  let queryProto;
8308
- if (isDocumentTarget(targetData.target)) {
8605
+ if (targetIsDocumentTarget(targetData.target)) {
8309
8606
  queryProto = toDocumentsTarget(localSerializer.remoteSerializer, targetData.target);
8310
8607
  }
8311
8608
  else {
@@ -8475,6 +8772,38 @@ class MemoryIndexManager {
8475
8772
  getCollectionParents(transaction, collectionId) {
8476
8773
  return PersistencePromise.resolve(this.collectionParentIndex.getEntries(collectionId));
8477
8774
  }
8775
+ addFieldIndex(transaction, index) {
8776
+ // Field indices are not supported with memory persistence.
8777
+ return PersistencePromise.resolve();
8778
+ }
8779
+ deleteFieldIndex(transaction, index) {
8780
+ // Field indices are not supported with memory persistence.
8781
+ return PersistencePromise.resolve();
8782
+ }
8783
+ getDocumentsMatchingTarget(transaction, fieldIndex, target) {
8784
+ // Field indices are not supported with memory persistence.
8785
+ return PersistencePromise.resolve(documentKeySet());
8786
+ }
8787
+ getFieldIndex(transaction, target) {
8788
+ // Field indices are not supported with memory persistence.
8789
+ return PersistencePromise.resolve(null);
8790
+ }
8791
+ getFieldIndexes(transaction, collectionGroup) {
8792
+ // Field indices are not supported with memory persistence.
8793
+ return PersistencePromise.resolve([]);
8794
+ }
8795
+ getNextCollectionGroupToUpdate(transaction) {
8796
+ // Field indices are not supported with memory persistence.
8797
+ return PersistencePromise.resolve(null);
8798
+ }
8799
+ updateCollectionGroup(transaction, collectionGroup, offset) {
8800
+ // Field indices are not supported with memory persistence.
8801
+ return PersistencePromise.resolve();
8802
+ }
8803
+ updateIndexEntries(transaction, documents) {
8804
+ // Field indices are not supported with memory persistence.
8805
+ return PersistencePromise.resolve();
8806
+ }
8478
8807
  }
8479
8808
  /**
8480
8809
  * Internal implementation of the collection-parent index exposed by MemoryIndexManager.
@@ -8583,6 +8912,38 @@ class IndexedDbIndexManager {
8583
8912
  return parentPaths;
8584
8913
  });
8585
8914
  }
8915
+ addFieldIndex(transaction, index) {
8916
+ // TODO(indexing): Implement
8917
+ return PersistencePromise.resolve();
8918
+ }
8919
+ deleteFieldIndex(transaction, index) {
8920
+ // TODO(indexing): Implement
8921
+ return PersistencePromise.resolve();
8922
+ }
8923
+ getDocumentsMatchingTarget(transaction, fieldIndex, target) {
8924
+ // TODO(indexing): Implement
8925
+ return PersistencePromise.resolve(documentKeySet());
8926
+ }
8927
+ getFieldIndex(transaction, target) {
8928
+ // TODO(indexing): Implement
8929
+ return PersistencePromise.resolve(null);
8930
+ }
8931
+ getFieldIndexes(transaction, collectionGroup) {
8932
+ // TODO(indexing): Implement
8933
+ return PersistencePromise.resolve([]);
8934
+ }
8935
+ getNextCollectionGroupToUpdate(transaction) {
8936
+ // TODO(indexing): Implement
8937
+ return PersistencePromise.resolve(null);
8938
+ }
8939
+ updateCollectionGroup(transaction, collectionGroup, offset) {
8940
+ // TODO(indexing): Implement
8941
+ return PersistencePromise.resolve();
8942
+ }
8943
+ updateIndexEntries(transaction, documents) {
8944
+ // TODO(indexing): Implement
8945
+ return PersistencePromise.resolve();
8946
+ }
8586
8947
  }
8587
8948
  /**
8588
8949
  * Helper to get a typed SimpleDbStore for the collectionParents
@@ -9753,7 +10114,7 @@ class IndexedDbLruDelegateImpl {
9753
10114
  // Our size accounting requires us to read all documents before
9754
10115
  // removing them.
9755
10116
  return changeBuffer.getEntry(txn, docKey).next(() => {
9756
- changeBuffer.removeEntry(docKey);
10117
+ changeBuffer.removeEntry(docKey, SnapshotVersion.min());
9757
10118
  return documentTargetStore(txn).delete(sentinelKey$1(docKey));
9758
10119
  });
9759
10120
  }
@@ -9966,27 +10327,19 @@ class ObjectMap {
9966
10327
  */
9967
10328
  class RemoteDocumentChangeBuffer {
9968
10329
  constructor() {
9969
- // A mapping of document key to the new cache entry that should be written (or null if any
9970
- // existing cache entry should be removed).
10330
+ // A mapping of document key to the new cache entry that should be written.
9971
10331
  this.changes = new ObjectMap(key => key.toString(), (l, r) => l.isEqual(r));
9972
10332
  this.changesApplied = false;
9973
10333
  }
9974
- getReadTime(key) {
9975
- const change = this.changes.get(key);
9976
- if (change) {
9977
- return change.readTime;
9978
- }
9979
- return SnapshotVersion.min();
9980
- }
9981
10334
  /**
9982
10335
  * Buffers a `RemoteDocumentCache.addEntry()` call.
9983
10336
  *
9984
10337
  * You can only modify documents that have already been retrieved via
9985
10338
  * `getEntry()/getEntries()` (enforced via IndexedDbs `apply()`).
9986
10339
  */
9987
- addEntry(document, readTime) {
10340
+ addEntry(document) {
9988
10341
  this.assertNotApplied();
9989
- this.changes.set(document.key, { document, readTime });
10342
+ this.changes.set(document.key, document);
9990
10343
  }
9991
10344
  /**
9992
10345
  * Buffers a `RemoteDocumentCache.removeEntry()` call.
@@ -9994,12 +10347,9 @@ class RemoteDocumentChangeBuffer {
9994
10347
  * You can only remove documents that have already been retrieved via
9995
10348
  * `getEntry()/getEntries()` (enforced via IndexedDbs `apply()`).
9996
10349
  */
9997
- removeEntry(key, readTime = null) {
10350
+ removeEntry(key, readTime) {
9998
10351
  this.assertNotApplied();
9999
- this.changes.set(key, {
10000
- document: MutableDocument.newInvalidDocument(key),
10001
- readTime
10002
- });
10352
+ this.changes.set(key, MutableDocument.newInvalidDocument(key).setReadTime(readTime));
10003
10353
  }
10004
10354
  /**
10005
10355
  * Looks up an entry in the cache. The buffered changes will first be checked,
@@ -10016,7 +10366,7 @@ class RemoteDocumentChangeBuffer {
10016
10366
  this.assertNotApplied();
10017
10367
  const bufferedEntry = this.changes.get(documentKey);
10018
10368
  if (bufferedEntry !== undefined) {
10019
- return PersistencePromise.resolve(bufferedEntry.document);
10369
+ return PersistencePromise.resolve(bufferedEntry);
10020
10370
  }
10021
10371
  else {
10022
10372
  return this.getFromCache(transaction, documentKey);
@@ -10227,7 +10577,7 @@ class IndexedDbRemoteDocumentCacheImpl {
10227
10577
  if (key.length !== immediateChildrenPathLength) {
10228
10578
  return;
10229
10579
  }
10230
- const document = fromDbRemoteDocument(this.serializer, dbRemoteDoc);
10580
+ const document = this.maybeDecodeDocument(DocumentKey.fromSegments(key), dbRemoteDoc);
10231
10581
  if (!query.path.isPrefixOf(document.key.path)) {
10232
10582
  control.done();
10233
10583
  }
@@ -10255,8 +10605,8 @@ class IndexedDbRemoteDocumentCacheImpl {
10255
10605
  return documentGlobalStore(txn).put(DbRemoteDocumentGlobal.key, metadata);
10256
10606
  }
10257
10607
  /**
10258
- * Decodes `remoteDoc` and returns the document (or null, if the document
10259
- * corresponds to the format used for sentinel deletes).
10608
+ * Decodes `dbRemoteDoc` and returns the document (or an invalid document if
10609
+ * the document corresponds to the format used for sentinel deletes).
10260
10610
  */
10261
10611
  maybeDecodeDocument(documentKey, dbRemoteDoc) {
10262
10612
  if (dbRemoteDoc) {
@@ -10350,8 +10700,8 @@ class IndexedDbRemoteDocumentChangeBuffer extends RemoteDocumentChangeBuffer {
10350
10700
  let collectionParents = new SortedSet((l, r) => primitiveComparator(l.canonicalString(), r.canonicalString()));
10351
10701
  this.changes.forEach((key, documentChange) => {
10352
10702
  const previousSize = this.documentSizes.get(key);
10353
- if (documentChange.document.isValidDocument()) {
10354
- const doc = toDbRemoteDocument(this.documentCache.serializer, documentChange.document, this.getReadTime(key));
10703
+ if (documentChange.isValidDocument()) {
10704
+ const doc = toDbRemoteDocument(this.documentCache.serializer, documentChange);
10355
10705
  collectionParents = collectionParents.add(key.path.popLast());
10356
10706
  const size = dbDocumentSize(doc);
10357
10707
  sizeDelta += size - previousSize;
@@ -10364,7 +10714,7 @@ class IndexedDbRemoteDocumentChangeBuffer extends RemoteDocumentChangeBuffer {
10364
10714
  // RemoteDocumentCache. This entry is represented by a NoDocument
10365
10715
  // with a version of 0 and ignored by `maybeDecodeDocument()` but
10366
10716
  // preserved in `getNewDocumentChanges()`.
10367
- const deletedDoc = toDbRemoteDocument(this.documentCache.serializer, MutableDocument.newNoDocument(key, SnapshotVersion.min()), this.getReadTime(key));
10717
+ const deletedDoc = toDbRemoteDocument(this.documentCache.serializer, documentChange.convertToNoDocument(SnapshotVersion.min()));
10368
10718
  promises.push(this.documentCache.addEntry(transaction, key, deletedDoc));
10369
10719
  }
10370
10720
  else {
@@ -10445,9 +10795,6 @@ class SchemaConverter {
10445
10795
  * and local feature development.
10446
10796
  */
10447
10797
  createOrUpgrade(db, txn, fromVersion, toVersion) {
10448
- hardAssert(fromVersion < toVersion &&
10449
- fromVersion >= 0 &&
10450
- toVersion <= SCHEMA_VERSION);
10451
10798
  const simpleDbTransaction = new SimpleDbTransaction('createOrUpgrade', txn);
10452
10799
  if (fromVersion < 1 && toVersion >= 1) {
10453
10800
  createPrimaryClientStore(db);
@@ -10514,6 +10861,11 @@ class SchemaConverter {
10514
10861
  createNamedQueriesStore(db);
10515
10862
  });
10516
10863
  }
10864
+ if (fromVersion < 12 && toVersion >= 12) {
10865
+ p = p.next(() => {
10866
+ createFieldIndex(db);
10867
+ });
10868
+ }
10517
10869
  return p;
10518
10870
  }
10519
10871
  addDocumentGlobal(txn) {
@@ -10720,6 +11072,17 @@ function createNamedQueriesStore(db) {
10720
11072
  db.createObjectStore(DbNamedQuery.store, {
10721
11073
  keyPath: DbNamedQuery.keyPath
10722
11074
  });
11075
+ }
11076
+ function createFieldIndex(db) {
11077
+ db.createObjectStore(DbIndexConfiguration.store, {
11078
+ keyPath: DbIndexConfiguration.keyPath
11079
+ });
11080
+ db.createObjectStore(DbIndexState.store, {
11081
+ keyPath: DbIndexState.keyPath
11082
+ });
11083
+ db.createObjectStore(DbIndexEntries.store, {
11084
+ keyPath: DbIndexEntries.keyPath
11085
+ });
10723
11086
  }
10724
11087
 
10725
11088
  /**
@@ -11951,14 +12314,14 @@ function localStoreApplyRemoteEventToLocalCache(localStore, remoteEvent) {
11951
12314
  }
11952
12315
  });
11953
12316
  let changedDocs = mutableDocumentMap();
11954
- remoteEvent.documentUpdates.forEach((key, doc) => {
12317
+ remoteEvent.documentUpdates.forEach(key => {
11955
12318
  if (remoteEvent.resolvedLimboDocuments.has(key)) {
11956
12319
  promises.push(localStoreImpl.persistence.referenceDelegate.updateLimboDocument(txn, key));
11957
12320
  }
11958
12321
  });
11959
12322
  // Each loop iteration only affects its "own" doc, so it's safe to get all the remote
11960
12323
  // documents in advance in a single call.
11961
- promises.push(populateDocumentChangeBuffer(txn, documentBuffer, remoteEvent.documentUpdates, remoteVersion, undefined).next(result => {
12324
+ promises.push(populateDocumentChangeBuffer(txn, documentBuffer, remoteEvent.documentUpdates).next(result => {
11962
12325
  changedDocs = result;
11963
12326
  }));
11964
12327
  // HACK: The only reason we allow a null snapshot version is so that we
@@ -11999,17 +12362,13 @@ function localStoreApplyRemoteEventToLocalCache(localStore, remoteEvent) {
11999
12362
  * Note: this function will use `documentVersions` if it is defined;
12000
12363
  * when it is not defined, resorts to `globalVersion`.
12001
12364
  */
12002
- function populateDocumentChangeBuffer(txn, documentBuffer, documents, globalVersion,
12003
- // TODO(wuandy): We could add `readTime` to MaybeDocument instead to remove
12004
- // this parameter.
12005
- documentVersions) {
12365
+ function populateDocumentChangeBuffer(txn, documentBuffer, documents) {
12006
12366
  let updatedKeys = documentKeySet();
12007
12367
  documents.forEach(k => (updatedKeys = updatedKeys.add(k)));
12008
12368
  return documentBuffer.getEntries(txn, updatedKeys).next(existingDocs => {
12009
12369
  let changedDocs = mutableDocumentMap();
12010
12370
  documents.forEach((key, doc) => {
12011
12371
  const existingDoc = existingDocs.get(key);
12012
- const docReadTime = (documentVersions === null || documentVersions === void 0 ? void 0 : documentVersions.get(key)) || globalVersion;
12013
12372
  // Note: The order of the steps below is important, since we want
12014
12373
  // to ensure that rejected limbo resolutions (which fabricate
12015
12374
  // NoDocuments with SnapshotVersion.min()) never add documents to
@@ -12018,14 +12377,14 @@ documentVersions) {
12018
12377
  // NoDocuments with SnapshotVersion.min() are used in manufactured
12019
12378
  // events. We remove these documents from cache since we lost
12020
12379
  // access.
12021
- documentBuffer.removeEntry(key, docReadTime);
12380
+ documentBuffer.removeEntry(key, doc.readTime);
12022
12381
  changedDocs = changedDocs.insert(key, doc);
12023
12382
  }
12024
12383
  else if (!existingDoc.isValidDocument() ||
12025
12384
  doc.version.compareTo(existingDoc.version) > 0 ||
12026
12385
  (doc.version.compareTo(existingDoc.version) === 0 &&
12027
12386
  existingDoc.hasPendingWrites)) {
12028
- documentBuffer.addEntry(doc, docReadTime);
12387
+ documentBuffer.addEntry(doc);
12029
12388
  changedDocs = changedDocs.insert(key, doc);
12030
12389
  }
12031
12390
  else {
@@ -12279,7 +12638,8 @@ function applyWriteToRemoteDocuments(localStoreImpl, txn, batchResult, documentB
12279
12638
  // We use the commitVersion as the readTime rather than the
12280
12639
  // document's updateTime since the updateTime is not advanced
12281
12640
  // for updates that do not modify the underlying document.
12282
- documentBuffer.addEntry(doc, batchResult.commitVersion);
12641
+ doc.setReadTime(batchResult.commitVersion);
12642
+ documentBuffer.addEntry(doc);
12283
12643
  }
12284
12644
  }
12285
12645
  });
@@ -12380,14 +12740,14 @@ async function localStoreApplyBundledDocuments(localStore, bundleConverter, docu
12380
12740
  const localStoreImpl = debugCast(localStore);
12381
12741
  let documentKeys = documentKeySet();
12382
12742
  let documentMap = mutableDocumentMap();
12383
- let versionMap = documentVersionMap();
12384
12743
  for (const bundleDoc of documents) {
12385
12744
  const documentKey = bundleConverter.toDocumentKey(bundleDoc.metadata.name);
12386
12745
  if (bundleDoc.document) {
12387
12746
  documentKeys = documentKeys.add(documentKey);
12388
12747
  }
12389
- documentMap = documentMap.insert(documentKey, bundleConverter.toMutableDocument(bundleDoc));
12390
- versionMap = versionMap.insert(documentKey, bundleConverter.toSnapshotVersion(bundleDoc.metadata.readTime));
12748
+ const doc = bundleConverter.toMutableDocument(bundleDoc);
12749
+ doc.setReadTime(bundleConverter.toSnapshotVersion(bundleDoc.metadata.readTime));
12750
+ documentMap = documentMap.insert(documentKey, doc);
12391
12751
  }
12392
12752
  const documentBuffer = localStoreImpl.remoteDocuments.newChangeBuffer({
12393
12753
  trackRemovals: true // Make sure document removals show up in `getNewDocumentChanges()`
@@ -12396,7 +12756,7 @@ async function localStoreApplyBundledDocuments(localStore, bundleConverter, docu
12396
12756
  // they will not get garbage collected right away.
12397
12757
  const umbrellaTargetData = await localStoreAllocateTarget(localStoreImpl, umbrellaTarget(bundleName));
12398
12758
  return localStoreImpl.persistence.runTransaction('Apply bundle documents', 'readwrite', txn => {
12399
- return populateDocumentChangeBuffer(txn, documentBuffer, documentMap, SnapshotVersion.min(), versionMap)
12759
+ return populateDocumentChangeBuffer(txn, documentBuffer, documentMap)
12400
12760
  .next(changedDocs => {
12401
12761
  documentBuffer.apply(txn);
12402
12762
  return changedDocs;
@@ -12877,15 +13237,14 @@ class MemoryRemoteDocumentCacheImpl {
12877
13237
  * All calls of `addEntry` are required to go through the RemoteDocumentChangeBuffer
12878
13238
  * returned by `newChangeBuffer()`.
12879
13239
  */
12880
- addEntry(transaction, doc, readTime) {
13240
+ addEntry(transaction, doc) {
12881
13241
  const key = doc.key;
12882
13242
  const entry = this.docs.get(key);
12883
13243
  const previousSize = entry ? entry.size : 0;
12884
13244
  const currentSize = this.sizer(doc);
12885
13245
  this.docs = this.docs.insert(key, {
12886
13246
  document: doc.mutableCopy(),
12887
- size: currentSize,
12888
- readTime
13247
+ size: currentSize
12889
13248
  });
12890
13249
  this.size += currentSize - previousSize;
12891
13250
  return this.indexManager.addToCollectionParentIndex(transaction, key.path.popLast());
@@ -12926,11 +13285,11 @@ class MemoryRemoteDocumentCacheImpl {
12926
13285
  const prefix = new DocumentKey(query.path.child(''));
12927
13286
  const iterator = this.docs.getIteratorFrom(prefix);
12928
13287
  while (iterator.hasNext()) {
12929
- const { key, value: { document, readTime } } = iterator.getNext();
13288
+ const { key, value: { document } } = iterator.getNext();
12930
13289
  if (!query.path.isPrefixOf(key.path)) {
12931
13290
  break;
12932
13291
  }
12933
- if (readTime.compareTo(sinceReadTime) <= 0) {
13292
+ if (document.readTime.compareTo(sinceReadTime) <= 0) {
12934
13293
  continue;
12935
13294
  }
12936
13295
  if (!queryMatches(query, document)) {
@@ -12974,8 +13333,8 @@ class MemoryRemoteDocumentChangeBuffer extends RemoteDocumentChangeBuffer {
12974
13333
  applyChanges(transaction) {
12975
13334
  const promises = [];
12976
13335
  this.changes.forEach((key, doc) => {
12977
- if (doc.document.isValidDocument()) {
12978
- promises.push(this.documentCache.addEntry(transaction, doc.document, this.getReadTime(key)));
13336
+ if (doc.isValidDocument()) {
13337
+ promises.push(this.documentCache.addEntry(transaction, doc));
12979
13338
  }
12980
13339
  else {
12981
13340
  this.documentCache.removeEntry(key);
@@ -13288,7 +13647,7 @@ class MemoryEagerDelegate {
13288
13647
  const key = DocumentKey.fromPath(path);
13289
13648
  return this.isReferenced(txn, key).next(isReferenced => {
13290
13649
  if (!isReferenced) {
13291
- changeBuffer.removeEntry(key);
13650
+ changeBuffer.removeEntry(key, SnapshotVersion.min());
13292
13651
  }
13293
13652
  });
13294
13653
  }).next(() => {
@@ -17068,6 +17427,40 @@ const nested = {
17068
17427
  id: 2
17069
17428
  }
17070
17429
  }
17430
+ },
17431
+ methodSignature: {
17432
+ rule: "repeated",
17433
+ type: "string",
17434
+ id: 1051,
17435
+ extend: "google.protobuf.MethodOptions"
17436
+ },
17437
+ defaultHost: {
17438
+ type: "string",
17439
+ id: 1049,
17440
+ extend: "google.protobuf.ServiceOptions"
17441
+ },
17442
+ oauthScopes: {
17443
+ type: "string",
17444
+ id: 1050,
17445
+ extend: "google.protobuf.ServiceOptions"
17446
+ },
17447
+ fieldBehavior: {
17448
+ rule: "repeated",
17449
+ type: "google.api.FieldBehavior",
17450
+ id: 1052,
17451
+ extend: "google.protobuf.FieldOptions"
17452
+ },
17453
+ FieldBehavior: {
17454
+ values: {
17455
+ FIELD_BEHAVIOR_UNSPECIFIED: 0,
17456
+ OPTIONAL: 1,
17457
+ REQUIRED: 2,
17458
+ OUTPUT_ONLY: 3,
17459
+ INPUT_ONLY: 4,
17460
+ IMMUTABLE: 5,
17461
+ UNORDERED_LIST: 6,
17462
+ NON_EMPTY_DEFAULT: 7
17463
+ }
17071
17464
  }
17072
17465
  }
17073
17466
  },
@@ -20311,6 +20704,9 @@ async function syncEngineRejectListen(syncEngine, targetId, err) {
20311
20704
  // store to purge a document. However, it would be tricky to keep all of
20312
20705
  // the local store's invariants with another method.
20313
20706
  let documentUpdates = new SortedMap(DocumentKey.comparator);
20707
+ // TODO(b/217189216): This limbo document should ideally have a read time,
20708
+ // so that it is picked up by any read-time based scans. The backend,
20709
+ // however, does not send a read time for target removals.
20314
20710
  documentUpdates = documentUpdates.insert(limboKey, MutableDocument.newNoDocument(limboKey, SnapshotVersion.min()));
20315
20711
  const resolvedLimboDocuments = documentKeySet().add(limboKey);
20316
20712
  const event = new RemoteEvent(SnapshotVersion.min(),
@@ -21878,13 +22274,16 @@ class FirestoreClient {
21878
22274
  this.user = User.UNAUTHENTICATED;
21879
22275
  this.clientId = AutoId.newId();
21880
22276
  this.authCredentialListener = () => Promise.resolve();
22277
+ this.appCheckCredentialListener = () => Promise.resolve();
21881
22278
  this.authCredentials.start(asyncQueue, async (user) => {
21882
22279
  logDebug(LOG_TAG$2, 'Received user=', user.uid);
21883
22280
  await this.authCredentialListener(user);
21884
22281
  this.user = user;
21885
22282
  });
21886
- // Register an empty credentials change listener to activate token refresh.
21887
- this.appCheckCredentials.start(asyncQueue, () => Promise.resolve());
22283
+ this.appCheckCredentials.start(asyncQueue, newAppCheckToken => {
22284
+ logDebug(LOG_TAG$2, 'Received new app check token=', newAppCheckToken);
22285
+ return this.appCheckCredentialListener(newAppCheckToken, this.user);
22286
+ });
21888
22287
  }
21889
22288
  async getConfiguration() {
21890
22289
  return {
@@ -21900,6 +22299,9 @@ class FirestoreClient {
21900
22299
  setCredentialChangeListener(listener) {
21901
22300
  this.authCredentialListener = listener;
21902
22301
  }
22302
+ setAppCheckTokenChangeListener(listener) {
22303
+ this.appCheckCredentialListener = listener;
22304
+ }
21903
22305
  /**
21904
22306
  * Checks that the client has not been terminated. Ensures that other methods on
21905
22307
  * this class cannot be called after the client is terminated.
@@ -21961,6 +22363,7 @@ async function setOnlineComponentProvider(client, onlineComponentProvider) {
21961
22363
  // The CredentialChangeListener of the online component provider takes
21962
22364
  // precedence over the offline component provider.
21963
22365
  client.setCredentialChangeListener(user => remoteStoreHandleCredentialChange(onlineComponentProvider.remoteStore, user));
22366
+ client.setAppCheckTokenChangeListener((_, user) => remoteStoreHandleCredentialChange(onlineComponentProvider.remoteStore, user));
21964
22367
  client.onlineComponents = onlineComponentProvider;
21965
22368
  }
21966
22369
  async function ensureOfflineComponents(client) {
@@ -22248,72 +22651,6 @@ function createBundleReader(data, serializer) {
22248
22651
  return newBundleReader(toByteStreamReader(content), serializer);
22249
22652
  }
22250
22653
 
22251
- /**
22252
- * @license
22253
- * Copyright 2017 Google LLC
22254
- *
22255
- * Licensed under the Apache License, Version 2.0 (the "License");
22256
- * you may not use this file except in compliance with the License.
22257
- * You may obtain a copy of the License at
22258
- *
22259
- * http://www.apache.org/licenses/LICENSE-2.0
22260
- *
22261
- * Unless required by applicable law or agreed to in writing, software
22262
- * distributed under the License is distributed on an "AS IS" BASIS,
22263
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22264
- * See the License for the specific language governing permissions and
22265
- * limitations under the License.
22266
- */
22267
- class DatabaseInfo {
22268
- /**
22269
- * Constructs a DatabaseInfo using the provided host, databaseId and
22270
- * persistenceKey.
22271
- *
22272
- * @param databaseId - The database to use.
22273
- * @param appId - The Firebase App Id.
22274
- * @param persistenceKey - A unique identifier for this Firestore's local
22275
- * storage (used in conjunction with the databaseId).
22276
- * @param host - The Firestore backend host to connect to.
22277
- * @param ssl - Whether to use SSL when connecting.
22278
- * @param forceLongPolling - Whether to use the forceLongPolling option
22279
- * when using WebChannel as the network transport.
22280
- * @param autoDetectLongPolling - Whether to use the detectBufferingProxy
22281
- * option when using WebChannel as the network transport.
22282
- * @param useFetchStreams Whether to use the Fetch API instead of
22283
- * XMLHTTPRequest
22284
- */
22285
- constructor(databaseId, appId, persistenceKey, host, ssl, forceLongPolling, autoDetectLongPolling, useFetchStreams) {
22286
- this.databaseId = databaseId;
22287
- this.appId = appId;
22288
- this.persistenceKey = persistenceKey;
22289
- this.host = host;
22290
- this.ssl = ssl;
22291
- this.forceLongPolling = forceLongPolling;
22292
- this.autoDetectLongPolling = autoDetectLongPolling;
22293
- this.useFetchStreams = useFetchStreams;
22294
- }
22295
- }
22296
- /** The default database name for a project. */
22297
- const DEFAULT_DATABASE_NAME = '(default)';
22298
- /**
22299
- * Represents the database ID a Firestore client is associated with.
22300
- * @internal
22301
- */
22302
- class DatabaseId {
22303
- constructor(projectId, database) {
22304
- this.projectId = projectId;
22305
- this.database = database ? database : DEFAULT_DATABASE_NAME;
22306
- }
22307
- get isDefaultDatabase() {
22308
- return this.database === DEFAULT_DATABASE_NAME;
22309
- }
22310
- isEqual(other) {
22311
- return (other instanceof DatabaseId &&
22312
- other.projectId === this.projectId &&
22313
- other.database === this.database);
22314
- }
22315
- }
22316
-
22317
22654
  /**
22318
22655
  * @license
22319
22656
  * Copyright 2020 Google LLC
@@ -23513,13 +23850,13 @@ function terminate(firestore) {
23513
23850
  /**
23514
23851
  * Loads a Firestore bundle into the local cache.
23515
23852
  *
23516
- * @param firestore - The {@link Firestore} instance to load bundles for for.
23517
- * @param bundleData - An object representing the bundle to be loaded. Valid objects are
23518
- * `ArrayBuffer`, `ReadableStream<Uint8Array>` or `string`.
23853
+ * @param firestore - The {@link Firestore} instance to load bundles for.
23854
+ * @param bundleData - An object representing the bundle to be loaded. Valid
23855
+ * objects are `ArrayBuffer`, `ReadableStream<Uint8Array>` or `string`.
23519
23856
  *
23520
- * @returns
23521
- * A `LoadBundleTask` object, which notifies callers with progress updates, and completion
23522
- * or error events. It can be used as a `Promise<LoadBundleTaskProgress>`.
23857
+ * @returns A `LoadBundleTask` object, which notifies callers with progress
23858
+ * updates, and completion or error events. It can be used as a
23859
+ * `Promise<LoadBundleTaskProgress>`.
23523
23860
  */
23524
23861
  function loadBundle(firestore, bundleData) {
23525
23862
  firestore = cast(firestore, Firestore);
@@ -23529,11 +23866,16 @@ function loadBundle(firestore, bundleData) {
23529
23866
  return resultTask;
23530
23867
  }
23531
23868
  /**
23532
- * Reads a Firestore {@link Query} from local cache, identified by the given name.
23869
+ * Reads a Firestore {@link Query} from local cache, identified by the given
23870
+ * name.
23533
23871
  *
23534
23872
  * The named queries are packaged into bundles on the server side (along
23535
- * with resulting documents), and loaded to local cache using `loadBundle`. Once in local
23536
- * cache, use this method to extract a {@link Query} by name.
23873
+ * with resulting documents), and loaded to local cache using `loadBundle`. Once
23874
+ * in local cache, use this method to extract a {@link Query} by name.
23875
+ *
23876
+ * @param firestore - The {@link Firestore} instance to read the query from.
23877
+ * @param name - The name of the query.
23878
+ * @returns A `Promise` that is resolved with the Query or `null`.
23537
23879
  */
23538
23880
  function namedQuery(firestore, name) {
23539
23881
  firestore = cast(firestore, Firestore);
@@ -24682,8 +25024,7 @@ class DocumentSnapshot extends DocumentSnapshot$1 {
24682
25024
  this.metadata = metadata;
24683
25025
  }
24684
25026
  /**
24685
- * Property of the `DocumentSnapshot` that signals whether or not the data
24686
- * exists. True if the document exists.
25027
+ * Returns whether or not the data exists. True if the document exists.
24687
25028
  */
24688
25029
  exists() {
24689
25030
  return super.exists();
@@ -25057,51 +25398,53 @@ function limitToLast(limit) {
25057
25398
  return new QueryLimitConstraint('limitToLast', limit, "L" /* Last */);
25058
25399
  }
25059
25400
  class QueryStartAtConstraint extends QueryConstraint {
25060
- constructor(type, _docOrFields, _before) {
25401
+ constructor(type, _docOrFields, _inclusive) {
25061
25402
  super();
25062
25403
  this.type = type;
25063
25404
  this._docOrFields = _docOrFields;
25064
- this._before = _before;
25405
+ this._inclusive = _inclusive;
25065
25406
  }
25066
25407
  _apply(query) {
25067
- const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._before);
25408
+ const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._inclusive);
25068
25409
  return new Query(query.firestore, query.converter, queryWithStartAt(query._query, bound));
25069
25410
  }
25070
25411
  }
25071
25412
  function startAt(...docOrFields) {
25072
- return new QueryStartAtConstraint('startAt', docOrFields, /*before=*/ true);
25413
+ return new QueryStartAtConstraint('startAt', docOrFields,
25414
+ /*inclusive=*/ true);
25073
25415
  }
25074
25416
  function startAfter(...docOrFields) {
25075
25417
  return new QueryStartAtConstraint('startAfter', docOrFields,
25076
- /*before=*/ false);
25418
+ /*inclusive=*/ false);
25077
25419
  }
25078
25420
  class QueryEndAtConstraint extends QueryConstraint {
25079
- constructor(type, _docOrFields, _before) {
25421
+ constructor(type, _docOrFields, _inclusive) {
25080
25422
  super();
25081
25423
  this.type = type;
25082
25424
  this._docOrFields = _docOrFields;
25083
- this._before = _before;
25425
+ this._inclusive = _inclusive;
25084
25426
  }
25085
25427
  _apply(query) {
25086
- const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._before);
25428
+ const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._inclusive);
25087
25429
  return new Query(query.firestore, query.converter, queryWithEndAt(query._query, bound));
25088
25430
  }
25089
25431
  }
25090
25432
  function endBefore(...docOrFields) {
25091
- return new QueryEndAtConstraint('endBefore', docOrFields, /*before=*/ true);
25433
+ return new QueryEndAtConstraint('endBefore', docOrFields,
25434
+ /*inclusive=*/ false);
25092
25435
  }
25093
25436
  function endAt(...docOrFields) {
25094
- return new QueryEndAtConstraint('endAt', docOrFields, /*before=*/ false);
25437
+ return new QueryEndAtConstraint('endAt', docOrFields, /*inclusive=*/ true);
25095
25438
  }
25096
25439
  /** Helper function to create a bound from a document or fields */
25097
- function newQueryBoundFromDocOrFields(query, methodName, docOrFields, before) {
25440
+ function newQueryBoundFromDocOrFields(query, methodName, docOrFields, inclusive) {
25098
25441
  docOrFields[0] = getModularInstance(docOrFields[0]);
25099
25442
  if (docOrFields[0] instanceof DocumentSnapshot$1) {
25100
- return newQueryBoundFromDocument(query._query, query.firestore._databaseId, methodName, docOrFields[0]._document, before);
25443
+ return newQueryBoundFromDocument(query._query, query.firestore._databaseId, methodName, docOrFields[0]._document, inclusive);
25101
25444
  }
25102
25445
  else {
25103
25446
  const reader = newUserDataReader(query.firestore);
25104
- return newQueryBoundFromFields(query._query, query.firestore._databaseId, reader, methodName, docOrFields, before);
25447
+ return newQueryBoundFromFields(query._query, query.firestore._databaseId, reader, methodName, docOrFields, inclusive);
25105
25448
  }
25106
25449
  }
25107
25450
  function newQueryFilter(query, methodName, dataReader, databaseId, fieldPath, op, value) {
@@ -25159,7 +25502,7 @@ function newQueryOrderBy(query, fieldPath, direction) {
25159
25502
  * of the query or if any of the fields in the order by are an uncommitted
25160
25503
  * server timestamp.
25161
25504
  */
25162
- function newQueryBoundFromDocument(query, databaseId, methodName, doc, before) {
25505
+ function newQueryBoundFromDocument(query, databaseId, methodName, doc, inclusive) {
25163
25506
  if (!doc) {
25164
25507
  throw new FirestoreError(Code.NOT_FOUND, `Can't use a DocumentSnapshot that doesn't exist for ` +
25165
25508
  `${methodName}().`);
@@ -25196,12 +25539,12 @@ function newQueryBoundFromDocument(query, databaseId, methodName, doc, before) {
25196
25539
  }
25197
25540
  }
25198
25541
  }
25199
- return new Bound(components, before);
25542
+ return new Bound(components, inclusive);
25200
25543
  }
25201
25544
  /**
25202
25545
  * Converts a list of field values to a `Bound` for the given query.
25203
25546
  */
25204
- function newQueryBoundFromFields(query, databaseId, dataReader, methodName, values, before) {
25547
+ function newQueryBoundFromFields(query, databaseId, dataReader, methodName, values, inclusive) {
25205
25548
  // Use explicit order by's because it has to match the query the user made
25206
25549
  const orderBy = query.explicitOrderBy;
25207
25550
  if (values.length > orderBy.length) {
@@ -25238,7 +25581,7 @@ function newQueryBoundFromFields(query, databaseId, dataReader, methodName, valu
25238
25581
  components.push(wrapped);
25239
25582
  }
25240
25583
  }
25241
- return new Bound(components, before);
25584
+ return new Bound(components, inclusive);
25242
25585
  }
25243
25586
  /**
25244
25587
  * Parses the given `documentIdValue` into a `ReferenceValue`, throwing
@@ -26223,6 +26566,71 @@ function writeBatch(firestore) {
26223
26566
  return new WriteBatch(firestore, mutations => executeWrite(firestore, mutations));
26224
26567
  }
26225
26568
 
26569
+ /**
26570
+ * @license
26571
+ * Copyright 2021 Google LLC
26572
+ *
26573
+ * Licensed under the Apache License, Version 2.0 (the "License");
26574
+ * you may not use this file except in compliance with the License.
26575
+ * You may obtain a copy of the License at
26576
+ *
26577
+ * http://www.apache.org/licenses/LICENSE-2.0
26578
+ *
26579
+ * Unless required by applicable law or agreed to in writing, software
26580
+ * distributed under the License is distributed on an "AS IS" BASIS,
26581
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26582
+ * See the License for the specific language governing permissions and
26583
+ * limitations under the License.
26584
+ */
26585
+ function setIndexConfiguration(firestore, jsonOrConfiguration) {
26586
+ firestore = cast(firestore, Firestore);
26587
+ ensureFirestoreConfigured(firestore);
26588
+ const indexConfiguration = typeof jsonOrConfiguration === 'string'
26589
+ ? tryParseJson(jsonOrConfiguration)
26590
+ : jsonOrConfiguration;
26591
+ const parsedIndexes = [];
26592
+ // PORTING NOTE: We don't return an error if the user has not enabled
26593
+ // persistence since `enableIndexeddbPersistence()` can fail on the Web.
26594
+ if (Array.isArray(indexConfiguration.indexes)) {
26595
+ for (const index of indexConfiguration.indexes) {
26596
+ const collectionGroup = tryGetString(index, 'collectionGroup');
26597
+ const segments = [];
26598
+ if (Array.isArray(index.fields)) {
26599
+ for (const field of index.fields) {
26600
+ const fieldPathString = tryGetString(field, 'fieldPath');
26601
+ const fieldPath = fieldPathFromDotSeparatedString('setIndexConfiguration', fieldPathString);
26602
+ if (field.arrayConfig === 'CONTAINS') {
26603
+ segments.push(new IndexSegment(fieldPath, 2 /* CONTAINS */));
26604
+ }
26605
+ else if (field.order === 'ASCENDING') {
26606
+ segments.push(new IndexSegment(fieldPath, 0 /* ASCENDING */));
26607
+ }
26608
+ else if (field.order === 'DESCENDING') {
26609
+ segments.push(new IndexSegment(fieldPath, 1 /* DESCENDING */));
26610
+ }
26611
+ }
26612
+ }
26613
+ parsedIndexes.push(new FieldIndex(FieldIndex.UNKNOWN_ID, collectionGroup, segments, IndexState.empty()));
26614
+ }
26615
+ }
26616
+ // TODO(indexing): Configure indexes
26617
+ return Promise.resolve();
26618
+ }
26619
+ function tryParseJson(json) {
26620
+ try {
26621
+ return JSON.parse(json);
26622
+ }
26623
+ catch (e) {
26624
+ throw new FirestoreError(Code.INVALID_ARGUMENT, 'Failed to parse JSON:' + e.message);
26625
+ }
26626
+ }
26627
+ function tryGetString(data, property) {
26628
+ if (typeof data[property] !== 'string') {
26629
+ throw new FirestoreError(Code.INVALID_ARGUMENT, 'Missing string value for: ' + property);
26630
+ }
26631
+ return data[property];
26632
+ }
26633
+
26226
26634
  /**
26227
26635
  * @license
26228
26636
  * Copyright 2021 Google LLC
@@ -26241,5 +26649,5 @@ function writeBatch(firestore) {
26241
26649
  */
26242
26650
  registerFirestore('node');
26243
26651
 
26244
- export { AbstractUserDataWriter, Bytes, CACHE_SIZE_UNLIMITED, CollectionReference, DocumentReference, DocumentSnapshot, FieldPath, FieldValue, Firestore, FirestoreError, GeoPoint, LoadBundleTask, Query, QueryConstraint, QueryDocumentSnapshot, QuerySnapshot, SnapshotMetadata, Timestamp, Transaction, WriteBatch, DatabaseId as _DatabaseId, DocumentKey as _DocumentKey, EmptyAppCheckTokenProvider as _EmptyAppCheckTokenProvider, EmptyAuthCredentialsProvider as _EmptyAuthCredentialsProvider, FieldPath$1 as _FieldPath, cast as _cast, debugAssert as _debugAssert, isBase64Available as _isBase64Available, logWarn as _logWarn, validateIsNotUsedTogether as _validateIsNotUsedTogether, addDoc, arrayRemove, arrayUnion, clearIndexedDbPersistence, collection, collectionGroup, connectFirestoreEmulator, deleteDoc, deleteField, disableNetwork, doc, documentId, enableIndexedDbPersistence, enableMultiTabIndexedDbPersistence, enableNetwork, endAt, endBefore, ensureFirestoreConfigured, executeWrite, getDoc, getDocFromCache, getDocFromServer, getDocs, getDocsFromCache, getDocsFromServer, getFirestore, increment, initializeFirestore, limit, limitToLast, loadBundle, namedQuery, onSnapshot, onSnapshotsInSync, orderBy, query, queryEqual, refEqual, runTransaction, serverTimestamp, setDoc, setLogLevel, snapshotEqual, startAfter, startAt, terminate, updateDoc, waitForPendingWrites, where, writeBatch };
26652
+ export { AbstractUserDataWriter, Bytes, CACHE_SIZE_UNLIMITED, CollectionReference, DocumentReference, DocumentSnapshot, FieldPath, FieldValue, Firestore, FirestoreError, GeoPoint, LoadBundleTask, Query, QueryConstraint, QueryDocumentSnapshot, QuerySnapshot, SnapshotMetadata, Timestamp, Transaction, WriteBatch, DatabaseId as _DatabaseId, DocumentKey as _DocumentKey, EmptyAppCheckTokenProvider as _EmptyAppCheckTokenProvider, EmptyAuthCredentialsProvider as _EmptyAuthCredentialsProvider, FieldPath$1 as _FieldPath, cast as _cast, debugAssert as _debugAssert, isBase64Available as _isBase64Available, logWarn as _logWarn, setIndexConfiguration as _setIndexConfiguration, validateIsNotUsedTogether as _validateIsNotUsedTogether, addDoc, arrayRemove, arrayUnion, clearIndexedDbPersistence, collection, collectionGroup, connectFirestoreEmulator, deleteDoc, deleteField, disableNetwork, doc, documentId, enableIndexedDbPersistence, enableMultiTabIndexedDbPersistence, enableNetwork, endAt, endBefore, ensureFirestoreConfigured, executeWrite, getDoc, getDocFromCache, getDocFromServer, getDocs, getDocsFromCache, getDocsFromServer, getFirestore, increment, initializeFirestore, limit, limitToLast, loadBundle, namedQuery, onSnapshot, onSnapshotsInSync, orderBy, query, queryEqual, refEqual, runTransaction, serverTimestamp, setDoc, setLogLevel, snapshotEqual, startAfter, startAt, terminate, updateDoc, waitForPendingWrites, where, writeBatch };
26245
26653
  //# sourceMappingURL=index.node.mjs.map