@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.
- package/CHANGELOG.md +10 -0
- package/dist/firestore/src/api/database.d.ts +14 -9
- package/dist/firestore/src/api/{query.d.ts → filter.d.ts} +0 -0
- package/dist/firestore/src/api/index_configuration.d.ts +117 -0
- package/dist/firestore/src/api/snapshot.d.ts +1 -2
- package/dist/firestore/src/api.d.ts +2 -1
- package/dist/firestore/src/core/database_info.d.ts +1 -0
- package/dist/firestore/src/core/firestore_client.d.ts +2 -0
- package/dist/firestore/src/core/target.d.ts +34 -5
- package/dist/firestore/src/lite-api/query.d.ts +2 -2
- package/dist/firestore/src/local/index_manager.d.ts +52 -0
- package/dist/firestore/src/local/indexeddb_index_manager.d.ts +11 -0
- package/dist/firestore/src/local/indexeddb_schema.d.ts +121 -7
- package/dist/firestore/src/local/local_serializer.d.ts +1 -1
- package/dist/firestore/src/local/memory_index_manager.d.ts +11 -0
- package/dist/firestore/src/local/remote_document_change_buffer.d.ts +3 -12
- package/dist/firestore/src/model/document.d.ts +7 -0
- package/dist/firestore/src/model/document_key.d.ts +1 -0
- package/dist/firestore/src/model/field_index.d.ts +156 -0
- package/dist/firestore/src/model/values.d.ts +7 -0
- package/dist/firestore/test/integration/api/index_configuration.test.d.ts +17 -0
- package/dist/firestore/test/unit/local/test_remote_document_cache.d.ts +1 -1
- package/dist/firestore/test/unit/model/field_index.test.d.ts +17 -0
- package/dist/firestore/test/unit/model/target.test.d.ts +17 -0
- package/dist/firestore/test/util/helpers.d.ts +8 -2
- package/dist/index.d.ts +16 -11
- package/dist/index.esm2017.js +2979 -2671
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm5.js +3036 -2815
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +644 -235
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/index.node.mjs +644 -236
- package/dist/index.node.mjs.map +1 -1
- package/dist/index.rn.js +2761 -2449
- package/dist/index.rn.js.map +1 -1
- package/dist/internal.d.ts +303 -25
- package/dist/lite/firestore/src/api/database.d.ts +14 -9
- package/dist/lite/firestore/src/api/{query.d.ts → filter.d.ts} +0 -0
- package/dist/lite/firestore/src/api/index_configuration.d.ts +117 -0
- package/dist/lite/firestore/src/api/snapshot.d.ts +1 -2
- package/dist/lite/firestore/src/api.d.ts +2 -1
- package/dist/lite/firestore/src/core/database_info.d.ts +1 -0
- package/dist/lite/firestore/src/core/firestore_client.d.ts +2 -0
- package/dist/lite/firestore/src/core/target.d.ts +34 -5
- package/dist/lite/firestore/src/lite-api/query.d.ts +2 -2
- package/dist/lite/firestore/src/local/index_manager.d.ts +52 -0
- package/dist/lite/firestore/src/local/indexeddb_index_manager.d.ts +11 -0
- package/dist/lite/firestore/src/local/indexeddb_schema.d.ts +121 -7
- package/dist/lite/firestore/src/local/local_serializer.d.ts +1 -1
- package/dist/lite/firestore/src/local/memory_index_manager.d.ts +11 -0
- package/dist/lite/firestore/src/local/remote_document_change_buffer.d.ts +3 -12
- package/dist/lite/firestore/src/model/document.d.ts +7 -0
- package/dist/lite/firestore/src/model/document_key.d.ts +1 -0
- package/dist/lite/firestore/src/model/field_index.d.ts +156 -0
- package/dist/lite/firestore/src/model/values.d.ts +7 -0
- package/dist/lite/firestore/test/integration/api/index_configuration.test.d.ts +17 -0
- package/dist/lite/firestore/test/unit/local/test_remote_document_cache.d.ts +1 -1
- package/dist/lite/firestore/test/unit/model/field_index.test.d.ts +17 -0
- package/dist/lite/firestore/test/unit/model/target.test.d.ts +17 -0
- package/dist/lite/firestore/test/util/helpers.d.ts +8 -2
- package/dist/lite/index.browser.esm2017.js +352 -338
- package/dist/lite/index.browser.esm2017.js.map +1 -1
- package/dist/lite/index.browser.esm5.js +334 -326
- package/dist/lite/index.browser.esm5.js.map +1 -1
- package/dist/lite/index.node.cjs.js +53 -34
- package/dist/lite/index.node.cjs.js.map +1 -1
- package/dist/lite/index.node.mjs +53 -34
- package/dist/lite/index.node.mjs.map +1 -1
- package/dist/lite/index.rn.esm2017.js +318 -304
- package/dist/lite/index.rn.esm2017.js.map +1 -1
- package/dist/lite/internal.d.ts +11 -2
- package/dist/lite/packages/firestore/dist/lite/index.browser.esm2017.d.ts +98 -97
- package/dist/lite/packages/firestore/src/api/database.d.ts +14 -9
- package/dist/lite/packages/firestore/src/api/{query.d.ts → filter.d.ts} +0 -0
- package/dist/lite/packages/firestore/src/api/index_configuration.d.ts +117 -0
- package/dist/lite/packages/firestore/src/api/snapshot.d.ts +1 -2
- package/dist/lite/packages/firestore/src/api.d.ts +2 -1
- package/dist/lite/packages/firestore/src/core/database_info.d.ts +1 -0
- package/dist/lite/packages/firestore/src/core/firestore_client.d.ts +2 -0
- package/dist/lite/packages/firestore/src/core/target.d.ts +34 -5
- package/dist/lite/packages/firestore/src/lite-api/query.d.ts +2 -2
- package/dist/lite/packages/firestore/src/local/index_manager.d.ts +52 -0
- package/dist/lite/packages/firestore/src/local/indexeddb_index_manager.d.ts +11 -0
- package/dist/lite/packages/firestore/src/local/indexeddb_schema.d.ts +121 -7
- package/dist/lite/packages/firestore/src/local/local_serializer.d.ts +1 -1
- package/dist/lite/packages/firestore/src/local/memory_index_manager.d.ts +11 -0
- package/dist/lite/packages/firestore/src/local/remote_document_change_buffer.d.ts +3 -12
- package/dist/lite/packages/firestore/src/model/document.d.ts +7 -0
- package/dist/lite/packages/firestore/src/model/document_key.d.ts +1 -0
- package/dist/lite/packages/firestore/src/model/field_index.d.ts +156 -0
- package/dist/lite/packages/firestore/src/model/values.d.ts +7 -0
- package/dist/lite/packages/firestore/test/integration/api/index_configuration.test.d.ts +17 -0
- package/dist/lite/packages/firestore/test/unit/local/test_remote_document_cache.d.ts +1 -1
- package/dist/lite/packages/firestore/test/unit/model/field_index.test.d.ts +17 -0
- package/dist/lite/packages/firestore/test/unit/model/target.test.d.ts +17 -0
- package/dist/lite/packages/firestore/test/util/helpers.d.ts +8 -2
- package/dist/lite/private.d.ts +9 -2
- package/dist/packages/firestore/dist/index.esm2017.d.ts +214 -191
- package/dist/packages/firestore/src/api/database.d.ts +14 -9
- package/dist/packages/firestore/src/api/{query.d.ts → filter.d.ts} +0 -0
- package/dist/packages/firestore/src/api/index_configuration.d.ts +117 -0
- package/dist/packages/firestore/src/api/snapshot.d.ts +1 -2
- package/dist/packages/firestore/src/api.d.ts +2 -1
- package/dist/packages/firestore/src/core/database_info.d.ts +1 -0
- package/dist/packages/firestore/src/core/firestore_client.d.ts +2 -0
- package/dist/packages/firestore/src/core/target.d.ts +34 -5
- package/dist/packages/firestore/src/lite-api/query.d.ts +2 -2
- package/dist/packages/firestore/src/local/index_manager.d.ts +52 -0
- package/dist/packages/firestore/src/local/indexeddb_index_manager.d.ts +11 -0
- package/dist/packages/firestore/src/local/indexeddb_schema.d.ts +121 -7
- package/dist/packages/firestore/src/local/local_serializer.d.ts +1 -1
- package/dist/packages/firestore/src/local/memory_index_manager.d.ts +11 -0
- package/dist/packages/firestore/src/local/remote_document_change_buffer.d.ts +3 -12
- package/dist/packages/firestore/src/model/document.d.ts +7 -0
- package/dist/packages/firestore/src/model/document_key.d.ts +1 -0
- package/dist/packages/firestore/src/model/field_index.d.ts +156 -0
- package/dist/packages/firestore/src/model/values.d.ts +7 -0
- package/dist/packages/firestore/test/integration/api/index_configuration.test.d.ts +17 -0
- package/dist/packages/firestore/test/unit/local/test_remote_document_cache.d.ts +1 -1
- package/dist/packages/firestore/test/unit/model/field_index.test.d.ts +17 -0
- package/dist/packages/firestore/test/unit/model/target.test.d.ts +17 -0
- package/dist/packages/firestore/test/util/helpers.d.ts +8 -2
- package/dist/private.d.ts +205 -25
- package/package.json +10 -10
package/dist/index.node.cjs.js
CHANGED
|
@@ -12,7 +12,7 @@ var grpcJs = require('@grpc/grpc-js');
|
|
|
12
12
|
var protoLoader = require('@grpc/proto-loader');
|
|
13
13
|
|
|
14
14
|
const name = "@firebase/firestore";
|
|
15
|
-
const version$1 = "3.4.
|
|
15
|
+
const version$1 = "3.4.4-canary.0482aa5b7";
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* @license
|
|
@@ -65,7 +65,7 @@ User.GOOGLE_CREDENTIALS = new User('google-credentials-uid');
|
|
|
65
65
|
User.FIRST_PARTY = new User('first-party-uid');
|
|
66
66
|
User.MOCK_USER = new User('mock-user');
|
|
67
67
|
|
|
68
|
-
const version = "9.6.
|
|
68
|
+
const version = "9.6.5-canary.0482aa5b7";
|
|
69
69
|
|
|
70
70
|
/**
|
|
71
71
|
* @license
|
|
@@ -1196,23 +1196,6 @@ function decodeResourcePath(path) {
|
|
|
1196
1196
|
}
|
|
1197
1197
|
return new ResourcePath(segments);
|
|
1198
1198
|
}
|
|
1199
|
-
|
|
1200
|
-
/**
|
|
1201
|
-
* @license
|
|
1202
|
-
* Copyright 2017 Google LLC
|
|
1203
|
-
*
|
|
1204
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1205
|
-
* you may not use this file except in compliance with the License.
|
|
1206
|
-
* You may obtain a copy of the License at
|
|
1207
|
-
*
|
|
1208
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1209
|
-
*
|
|
1210
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
1211
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1212
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1213
|
-
* See the License for the specific language governing permissions and
|
|
1214
|
-
* limitations under the License.
|
|
1215
|
-
*/
|
|
1216
1199
|
/**
|
|
1217
1200
|
* Schema Version for the Web client:
|
|
1218
1201
|
* 1. Initial version including Mutation Queue, Query Cache, and Remote
|
|
@@ -1231,6 +1214,7 @@ function decodeResourcePath(path) {
|
|
|
1231
1214
|
* an auto-incrementing ID. This is required for Index-Free queries.
|
|
1232
1215
|
* 10. Rewrite the canonical IDs to the explicit Protobuf-based format.
|
|
1233
1216
|
* 11. Add bundles and named_queries for bundle support.
|
|
1217
|
+
* 12. Add indexing support.
|
|
1234
1218
|
*/
|
|
1235
1219
|
const SCHEMA_VERSION = 11;
|
|
1236
1220
|
/**
|
|
@@ -1757,9 +1741,7 @@ class DbClientMetadata {
|
|
|
1757
1741
|
DbClientMetadata.store = 'clientMetadata';
|
|
1758
1742
|
/** Keys are automatically assigned via the clientId properties. */
|
|
1759
1743
|
DbClientMetadata.keyPath = 'clientId';
|
|
1760
|
-
/**
|
|
1761
|
-
* A object representing a bundle loaded by the SDK.
|
|
1762
|
-
*/
|
|
1744
|
+
/** An object representing a bundle loaded by the SDK. */
|
|
1763
1745
|
class DbBundle {
|
|
1764
1746
|
constructor(
|
|
1765
1747
|
/** The ID of the loaded bundle. */
|
|
@@ -1776,9 +1758,7 @@ class DbBundle {
|
|
|
1776
1758
|
/** Name of the IndexedDb object store. */
|
|
1777
1759
|
DbBundle.store = 'bundles';
|
|
1778
1760
|
DbBundle.keyPath = 'bundleId';
|
|
1779
|
-
/**
|
|
1780
|
-
* A object representing a named query loaded by the SDK via a bundle.
|
|
1781
|
-
*/
|
|
1761
|
+
/** An object representing a named query loaded by the SDK via a bundle. */
|
|
1782
1762
|
class DbNamedQuery {
|
|
1783
1763
|
constructor(
|
|
1784
1764
|
/** The name of the query. */
|
|
@@ -1795,6 +1775,93 @@ class DbNamedQuery {
|
|
|
1795
1775
|
/** Name of the IndexedDb object store. */
|
|
1796
1776
|
DbNamedQuery.store = 'namedQueries';
|
|
1797
1777
|
DbNamedQuery.keyPath = 'name';
|
|
1778
|
+
/** An object representing the global configuration for a field index. */
|
|
1779
|
+
class DbIndexConfiguration {
|
|
1780
|
+
constructor(
|
|
1781
|
+
/** The index id for this entry. */
|
|
1782
|
+
indexId,
|
|
1783
|
+
/** The collection group this index belongs to. */
|
|
1784
|
+
collectionGroup,
|
|
1785
|
+
/** The fields to index for this index. */
|
|
1786
|
+
fields) {
|
|
1787
|
+
this.indexId = indexId;
|
|
1788
|
+
this.collectionGroup = collectionGroup;
|
|
1789
|
+
this.fields = fields;
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1792
|
+
/** Name of the IndexedDb object store. */
|
|
1793
|
+
DbIndexConfiguration.store = 'indexConfiguration';
|
|
1794
|
+
DbIndexConfiguration.keyPath = 'indexId';
|
|
1795
|
+
/**
|
|
1796
|
+
* An object describing how up-to-date the index backfill is for each user and
|
|
1797
|
+
* index.
|
|
1798
|
+
*/
|
|
1799
|
+
class DbIndexState {
|
|
1800
|
+
constructor(
|
|
1801
|
+
/** The index id for this entry. */
|
|
1802
|
+
indexId,
|
|
1803
|
+
/** The user id for this entry. */
|
|
1804
|
+
uid,
|
|
1805
|
+
/**
|
|
1806
|
+
* A number that indicates when the index was last updated (relative to
|
|
1807
|
+
* other indexes).
|
|
1808
|
+
*/
|
|
1809
|
+
sequenceNumber,
|
|
1810
|
+
/**
|
|
1811
|
+
* The latest read time that has been indexed by Firestore for this field
|
|
1812
|
+
* index. Set to `{seconds: 0, nanos: 0}` if no documents have been indexed.
|
|
1813
|
+
*/
|
|
1814
|
+
readTime,
|
|
1815
|
+
/**
|
|
1816
|
+
* The last document that has been indexed for this field index. Empty if
|
|
1817
|
+
* no documents have been indexed.
|
|
1818
|
+
*/
|
|
1819
|
+
documentKey,
|
|
1820
|
+
/**
|
|
1821
|
+
* The largest mutation batch id that has been processed for this index. -1
|
|
1822
|
+
* if no mutations have been indexed.
|
|
1823
|
+
*/
|
|
1824
|
+
largestBatchId) {
|
|
1825
|
+
this.indexId = indexId;
|
|
1826
|
+
this.uid = uid;
|
|
1827
|
+
this.sequenceNumber = sequenceNumber;
|
|
1828
|
+
this.readTime = readTime;
|
|
1829
|
+
this.documentKey = documentKey;
|
|
1830
|
+
this.largestBatchId = largestBatchId;
|
|
1831
|
+
}
|
|
1832
|
+
}
|
|
1833
|
+
/** Name of the IndexedDb object store. */
|
|
1834
|
+
DbIndexState.store = 'indexState';
|
|
1835
|
+
DbIndexState.keyPath = ['indexId', 'uid'];
|
|
1836
|
+
/** An object that stores the encoded entries for all documents and fields. */
|
|
1837
|
+
class DbIndexEntries {
|
|
1838
|
+
constructor(
|
|
1839
|
+
/** The index id for this entry. */
|
|
1840
|
+
indexId,
|
|
1841
|
+
/** The user id for this entry. */
|
|
1842
|
+
uid,
|
|
1843
|
+
/** The encoded array index value for this entry. */
|
|
1844
|
+
arrayValue,
|
|
1845
|
+
/** The encoded directional value for equality and inequality filters. */
|
|
1846
|
+
directionalValue,
|
|
1847
|
+
/** The document key this entry points to. */
|
|
1848
|
+
documentKey) {
|
|
1849
|
+
this.indexId = indexId;
|
|
1850
|
+
this.uid = uid;
|
|
1851
|
+
this.arrayValue = arrayValue;
|
|
1852
|
+
this.directionalValue = directionalValue;
|
|
1853
|
+
this.documentKey = documentKey;
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
1856
|
+
/** Name of the IndexedDb object store. */
|
|
1857
|
+
DbIndexEntries.store = 'indexEntries';
|
|
1858
|
+
DbIndexEntries.keyPath = [
|
|
1859
|
+
'indexId',
|
|
1860
|
+
'uid',
|
|
1861
|
+
'arrayValue',
|
|
1862
|
+
'directionalValue',
|
|
1863
|
+
'documentKey'
|
|
1864
|
+
];
|
|
1798
1865
|
// Visible for testing
|
|
1799
1866
|
const V1_STORES = [
|
|
1800
1867
|
DbMutationQueue.store,
|
|
@@ -1809,7 +1876,6 @@ const V1_STORES = [
|
|
|
1809
1876
|
// V2 is no longer usable (see comment at top of file)
|
|
1810
1877
|
// Visible for testing
|
|
1811
1878
|
const V3_STORES = V1_STORES;
|
|
1812
|
-
// Visible for testing
|
|
1813
1879
|
// Note: DbRemoteDocumentChanges is no longer used and dropped with v9.
|
|
1814
1880
|
const V4_STORES = [...V3_STORES, DbClientMetadata.store];
|
|
1815
1881
|
// V5 does not change the set of stores.
|
|
@@ -1819,6 +1885,12 @@ const V8_STORES = [...V6_STORES, DbCollectionParent.store];
|
|
|
1819
1885
|
// V9 does not change the set of stores.
|
|
1820
1886
|
// V10 does not change the set of stores.
|
|
1821
1887
|
const V11_STORES = [...V8_STORES, DbBundle.store, DbNamedQuery.store];
|
|
1888
|
+
[
|
|
1889
|
+
...V11_STORES,
|
|
1890
|
+
DbIndexConfiguration.store,
|
|
1891
|
+
DbIndexState.store,
|
|
1892
|
+
DbIndexEntries.store
|
|
1893
|
+
];
|
|
1822
1894
|
/**
|
|
1823
1895
|
* The list of all default IndexedDB stores used throughout the SDK. This is
|
|
1824
1896
|
* used when creating transactions so that access across all stores is done
|
|
@@ -3378,6 +3450,75 @@ function getLocalWriteTime(value) {
|
|
|
3378
3450
|
return new Timestamp(localWriteTime.seconds, localWriteTime.nanos);
|
|
3379
3451
|
}
|
|
3380
3452
|
|
|
3453
|
+
/**
|
|
3454
|
+
* @license
|
|
3455
|
+
* Copyright 2017 Google LLC
|
|
3456
|
+
*
|
|
3457
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
3458
|
+
* you may not use this file except in compliance with the License.
|
|
3459
|
+
* You may obtain a copy of the License at
|
|
3460
|
+
*
|
|
3461
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
3462
|
+
*
|
|
3463
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
3464
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
3465
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
3466
|
+
* See the License for the specific language governing permissions and
|
|
3467
|
+
* limitations under the License.
|
|
3468
|
+
*/
|
|
3469
|
+
class DatabaseInfo {
|
|
3470
|
+
/**
|
|
3471
|
+
* Constructs a DatabaseInfo using the provided host, databaseId and
|
|
3472
|
+
* persistenceKey.
|
|
3473
|
+
*
|
|
3474
|
+
* @param databaseId - The database to use.
|
|
3475
|
+
* @param appId - The Firebase App Id.
|
|
3476
|
+
* @param persistenceKey - A unique identifier for this Firestore's local
|
|
3477
|
+
* storage (used in conjunction with the databaseId).
|
|
3478
|
+
* @param host - The Firestore backend host to connect to.
|
|
3479
|
+
* @param ssl - Whether to use SSL when connecting.
|
|
3480
|
+
* @param forceLongPolling - Whether to use the forceLongPolling option
|
|
3481
|
+
* when using WebChannel as the network transport.
|
|
3482
|
+
* @param autoDetectLongPolling - Whether to use the detectBufferingProxy
|
|
3483
|
+
* option when using WebChannel as the network transport.
|
|
3484
|
+
* @param useFetchStreams Whether to use the Fetch API instead of
|
|
3485
|
+
* XMLHTTPRequest
|
|
3486
|
+
*/
|
|
3487
|
+
constructor(databaseId, appId, persistenceKey, host, ssl, forceLongPolling, autoDetectLongPolling, useFetchStreams) {
|
|
3488
|
+
this.databaseId = databaseId;
|
|
3489
|
+
this.appId = appId;
|
|
3490
|
+
this.persistenceKey = persistenceKey;
|
|
3491
|
+
this.host = host;
|
|
3492
|
+
this.ssl = ssl;
|
|
3493
|
+
this.forceLongPolling = forceLongPolling;
|
|
3494
|
+
this.autoDetectLongPolling = autoDetectLongPolling;
|
|
3495
|
+
this.useFetchStreams = useFetchStreams;
|
|
3496
|
+
}
|
|
3497
|
+
}
|
|
3498
|
+
/** The default database name for a project. */
|
|
3499
|
+
const DEFAULT_DATABASE_NAME = '(default)';
|
|
3500
|
+
/**
|
|
3501
|
+
* Represents the database ID a Firestore client is associated with.
|
|
3502
|
+
* @internal
|
|
3503
|
+
*/
|
|
3504
|
+
class DatabaseId {
|
|
3505
|
+
constructor(projectId, database) {
|
|
3506
|
+
this.projectId = projectId;
|
|
3507
|
+
this.database = database ? database : DEFAULT_DATABASE_NAME;
|
|
3508
|
+
}
|
|
3509
|
+
static empty() {
|
|
3510
|
+
return new DatabaseId('', '');
|
|
3511
|
+
}
|
|
3512
|
+
get isDefaultDatabase() {
|
|
3513
|
+
return this.database === DEFAULT_DATABASE_NAME;
|
|
3514
|
+
}
|
|
3515
|
+
isEqual(other) {
|
|
3516
|
+
return (other instanceof DatabaseId &&
|
|
3517
|
+
other.projectId === this.projectId &&
|
|
3518
|
+
other.database === this.database);
|
|
3519
|
+
}
|
|
3520
|
+
}
|
|
3521
|
+
|
|
3381
3522
|
/**
|
|
3382
3523
|
* @license
|
|
3383
3524
|
* Copyright 2017 Google LLC
|
|
@@ -3449,6 +3590,9 @@ class DocumentKey {
|
|
|
3449
3590
|
static fromName(name) {
|
|
3450
3591
|
return new DocumentKey(ResourcePath.fromString(name).popFirst(5));
|
|
3451
3592
|
}
|
|
3593
|
+
static empty() {
|
|
3594
|
+
return new DocumentKey(ResourcePath.emptyPath());
|
|
3595
|
+
}
|
|
3452
3596
|
/** Returns true if the document is in the specified collectionId. */
|
|
3453
3597
|
hasCollectionId(collectionId) {
|
|
3454
3598
|
return (this.path.length >= 2 &&
|
|
@@ -4097,10 +4241,11 @@ function extractFieldMask(value) {
|
|
|
4097
4241
|
* from all views.
|
|
4098
4242
|
*/
|
|
4099
4243
|
class MutableDocument {
|
|
4100
|
-
constructor(key, documentType, version, data, documentState) {
|
|
4244
|
+
constructor(key, documentType, version, readTime, data, documentState) {
|
|
4101
4245
|
this.key = key;
|
|
4102
4246
|
this.documentType = documentType;
|
|
4103
4247
|
this.version = version;
|
|
4248
|
+
this.readTime = readTime;
|
|
4104
4249
|
this.data = data;
|
|
4105
4250
|
this.documentState = documentState;
|
|
4106
4251
|
}
|
|
@@ -4109,18 +4254,18 @@ class MutableDocument {
|
|
|
4109
4254
|
* base document for mutations.
|
|
4110
4255
|
*/
|
|
4111
4256
|
static newInvalidDocument(documentKey) {
|
|
4112
|
-
return new MutableDocument(documentKey, 0 /* INVALID */, SnapshotVersion.min(), ObjectValue.empty(), 0 /* SYNCED */);
|
|
4257
|
+
return new MutableDocument(documentKey, 0 /* INVALID */, SnapshotVersion.min(), SnapshotVersion.min(), ObjectValue.empty(), 0 /* SYNCED */);
|
|
4113
4258
|
}
|
|
4114
4259
|
/**
|
|
4115
4260
|
* Creates a new document that is known to exist with the given data at the
|
|
4116
4261
|
* given version.
|
|
4117
4262
|
*/
|
|
4118
4263
|
static newFoundDocument(documentKey, version, value) {
|
|
4119
|
-
return new MutableDocument(documentKey, 1 /* FOUND_DOCUMENT */, version, value, 0 /* SYNCED */);
|
|
4264
|
+
return new MutableDocument(documentKey, 1 /* FOUND_DOCUMENT */, version, SnapshotVersion.min(), value, 0 /* SYNCED */);
|
|
4120
4265
|
}
|
|
4121
4266
|
/** Creates a new document that is known to not exist at the given version. */
|
|
4122
4267
|
static newNoDocument(documentKey, version) {
|
|
4123
|
-
return new MutableDocument(documentKey, 2 /* NO_DOCUMENT */, version, ObjectValue.empty(), 0 /* SYNCED */);
|
|
4268
|
+
return new MutableDocument(documentKey, 2 /* NO_DOCUMENT */, version, SnapshotVersion.min(), ObjectValue.empty(), 0 /* SYNCED */);
|
|
4124
4269
|
}
|
|
4125
4270
|
/**
|
|
4126
4271
|
* Creates a new document that is known to exist at the given version but
|
|
@@ -4128,7 +4273,7 @@ class MutableDocument {
|
|
|
4128
4273
|
* base document).
|
|
4129
4274
|
*/
|
|
4130
4275
|
static newUnknownDocument(documentKey, version) {
|
|
4131
|
-
return new MutableDocument(documentKey, 3 /* UNKNOWN_DOCUMENT */, version, ObjectValue.empty(), 2 /* HAS_COMMITTED_MUTATIONS */);
|
|
4276
|
+
return new MutableDocument(documentKey, 3 /* UNKNOWN_DOCUMENT */, version, SnapshotVersion.min(), ObjectValue.empty(), 2 /* HAS_COMMITTED_MUTATIONS */);
|
|
4132
4277
|
}
|
|
4133
4278
|
/**
|
|
4134
4279
|
* Changes the document type to indicate that it exists and that its version
|
|
@@ -4172,6 +4317,10 @@ class MutableDocument {
|
|
|
4172
4317
|
this.documentState = 1 /* HAS_LOCAL_MUTATIONS */;
|
|
4173
4318
|
return this;
|
|
4174
4319
|
}
|
|
4320
|
+
setReadTime(readTime) {
|
|
4321
|
+
this.readTime = readTime;
|
|
4322
|
+
return this;
|
|
4323
|
+
}
|
|
4175
4324
|
get hasLocalMutations() {
|
|
4176
4325
|
return this.documentState === 1 /* HAS_LOCAL_MUTATIONS */;
|
|
4177
4326
|
}
|
|
@@ -4202,7 +4351,7 @@ class MutableDocument {
|
|
|
4202
4351
|
this.data.isEqual(other.data));
|
|
4203
4352
|
}
|
|
4204
4353
|
mutableCopy() {
|
|
4205
|
-
return new MutableDocument(this.key, this.documentType, this.version, this.data.clone(), this.documentState);
|
|
4354
|
+
return new MutableDocument(this.key, this.documentType, this.version, this.readTime, this.data.clone(), this.documentState);
|
|
4206
4355
|
}
|
|
4207
4356
|
toString() {
|
|
4208
4357
|
return (`Document(${this.key}, ${this.version}, ${JSON.stringify(this.data.value)}, ` +
|
|
@@ -4225,6 +4374,125 @@ function compareDocumentsByField(field, d1, d2) {
|
|
|
4225
4374
|
}
|
|
4226
4375
|
}
|
|
4227
4376
|
|
|
4377
|
+
/**
|
|
4378
|
+
* @license
|
|
4379
|
+
* Copyright 2021 Google LLC
|
|
4380
|
+
*
|
|
4381
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4382
|
+
* you may not use this file except in compliance with the License.
|
|
4383
|
+
* You may obtain a copy of the License at
|
|
4384
|
+
*
|
|
4385
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
4386
|
+
*
|
|
4387
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
4388
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
4389
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
4390
|
+
* See the License for the specific language governing permissions and
|
|
4391
|
+
* limitations under the License.
|
|
4392
|
+
*/
|
|
4393
|
+
/**
|
|
4394
|
+
* The initial mutation batch id for each index. Gets updated during index
|
|
4395
|
+
* backfill.
|
|
4396
|
+
*/
|
|
4397
|
+
const INITIAL_LARGEST_BATCH_ID = -1;
|
|
4398
|
+
/**
|
|
4399
|
+
* The initial sequence number for each index. Gets updated during index
|
|
4400
|
+
* backfill.
|
|
4401
|
+
*/
|
|
4402
|
+
const INITIAL_SEQUENCE_NUMBER = 0;
|
|
4403
|
+
/**
|
|
4404
|
+
* An index definition for field indexes in Firestore.
|
|
4405
|
+
*
|
|
4406
|
+
* Every index is associated with a collection. The definition contains a list
|
|
4407
|
+
* of fields and their index kind (which can be `ASCENDING`, `DESCENDING` or
|
|
4408
|
+
* `CONTAINS` for ArrayContains/ArrayContainsAny queries).
|
|
4409
|
+
*
|
|
4410
|
+
* Unlike the backend, the SDK does not differentiate between collection or
|
|
4411
|
+
* collection group-scoped indices. Every index can be used for both single
|
|
4412
|
+
* collection and collection group queries.
|
|
4413
|
+
*/
|
|
4414
|
+
class FieldIndex {
|
|
4415
|
+
constructor(
|
|
4416
|
+
/**
|
|
4417
|
+
* The index ID. Returns -1 if the index ID is not available (e.g. the index
|
|
4418
|
+
* has not yet been persisted).
|
|
4419
|
+
*/
|
|
4420
|
+
indexId,
|
|
4421
|
+
/** The collection ID this index applies to. */
|
|
4422
|
+
collectionGroup,
|
|
4423
|
+
/** The field segments for this index. */
|
|
4424
|
+
segments,
|
|
4425
|
+
/** Shows how up-to-date the index is for the current user. */
|
|
4426
|
+
indexState) {
|
|
4427
|
+
this.indexId = indexId;
|
|
4428
|
+
this.collectionGroup = collectionGroup;
|
|
4429
|
+
this.segments = segments;
|
|
4430
|
+
this.indexState = indexState;
|
|
4431
|
+
}
|
|
4432
|
+
}
|
|
4433
|
+
/** An ID for an index that has not yet been added to persistence. */
|
|
4434
|
+
FieldIndex.UNKNOWN_ID = -1;
|
|
4435
|
+
/** An index component consisting of field path and index type. */
|
|
4436
|
+
class IndexSegment {
|
|
4437
|
+
constructor(
|
|
4438
|
+
/** The field path of the component. */
|
|
4439
|
+
fieldPath,
|
|
4440
|
+
/** The fields sorting order. */
|
|
4441
|
+
kind) {
|
|
4442
|
+
this.fieldPath = fieldPath;
|
|
4443
|
+
this.kind = kind;
|
|
4444
|
+
}
|
|
4445
|
+
}
|
|
4446
|
+
/**
|
|
4447
|
+
* Stores the "high water mark" that indicates how updated the Index is for the
|
|
4448
|
+
* current user.
|
|
4449
|
+
*/
|
|
4450
|
+
class IndexState {
|
|
4451
|
+
constructor(
|
|
4452
|
+
/**
|
|
4453
|
+
* Indicates when the index was last updated (relative to other indexes).
|
|
4454
|
+
*/
|
|
4455
|
+
sequenceNumber,
|
|
4456
|
+
/** The the latest indexed read time, document and batch id. */
|
|
4457
|
+
offset) {
|
|
4458
|
+
this.sequenceNumber = sequenceNumber;
|
|
4459
|
+
this.offset = offset;
|
|
4460
|
+
}
|
|
4461
|
+
/** The state of an index that has not yet been backfilled. */
|
|
4462
|
+
static empty() {
|
|
4463
|
+
return new IndexState(INITIAL_SEQUENCE_NUMBER, IndexOffset.min());
|
|
4464
|
+
}
|
|
4465
|
+
}
|
|
4466
|
+
/**
|
|
4467
|
+
* Stores the latest read time, document and batch ID that were processed for an
|
|
4468
|
+
* index.
|
|
4469
|
+
*/
|
|
4470
|
+
class IndexOffset {
|
|
4471
|
+
constructor(
|
|
4472
|
+
/**
|
|
4473
|
+
* The latest read time version that has been indexed by Firestore for this
|
|
4474
|
+
* field index.
|
|
4475
|
+
*/
|
|
4476
|
+
readTime,
|
|
4477
|
+
/**
|
|
4478
|
+
* The key of the last document that was indexed for this query. Use
|
|
4479
|
+
* `DocumentKey.empty()` if no document has been indexed.
|
|
4480
|
+
*/
|
|
4481
|
+
documentKey,
|
|
4482
|
+
/*
|
|
4483
|
+
* The largest mutation batch id that's been processed by Firestore.
|
|
4484
|
+
*/
|
|
4485
|
+
largestBatchId) {
|
|
4486
|
+
this.readTime = readTime;
|
|
4487
|
+
this.documentKey = documentKey;
|
|
4488
|
+
this.largestBatchId = largestBatchId;
|
|
4489
|
+
}
|
|
4490
|
+
/** The state of an index that has not yet been backfilled. */
|
|
4491
|
+
static min() {
|
|
4492
|
+
return new IndexOffset(SnapshotVersion.min(), DocumentKey.empty(), INITIAL_LARGEST_BATCH_ID);
|
|
4493
|
+
}
|
|
4494
|
+
}
|
|
4495
|
+
|
|
4228
4496
|
/**
|
|
4229
4497
|
* @license
|
|
4230
4498
|
* Copyright 2019 Google LLC
|
|
@@ -4268,27 +4536,29 @@ function newTarget(path, collectionGroup = null, orderBy = [], filters = [], lim
|
|
|
4268
4536
|
function canonifyTarget(target) {
|
|
4269
4537
|
const targetImpl = debugCast(target);
|
|
4270
4538
|
if (targetImpl.memoizedCanonicalId === null) {
|
|
4271
|
-
let
|
|
4539
|
+
let str = targetImpl.path.canonicalString();
|
|
4272
4540
|
if (targetImpl.collectionGroup !== null) {
|
|
4273
|
-
|
|
4541
|
+
str += '|cg:' + targetImpl.collectionGroup;
|
|
4274
4542
|
}
|
|
4275
|
-
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
|
|
4543
|
+
str += '|f:';
|
|
4544
|
+
str += targetImpl.filters.map(f => canonifyFilter(f)).join(',');
|
|
4545
|
+
str += '|ob:';
|
|
4546
|
+
str += targetImpl.orderBy.map(o => canonifyOrderBy(o)).join(',');
|
|
4279
4547
|
if (!isNullOrUndefined(targetImpl.limit)) {
|
|
4280
|
-
|
|
4281
|
-
|
|
4548
|
+
str += '|l:';
|
|
4549
|
+
str += targetImpl.limit;
|
|
4282
4550
|
}
|
|
4283
4551
|
if (targetImpl.startAt) {
|
|
4284
|
-
|
|
4285
|
-
|
|
4552
|
+
str += '|lb:';
|
|
4553
|
+
str += targetImpl.startAt.inclusive ? 'b:' : 'a:';
|
|
4554
|
+
str += targetImpl.startAt.position.map(p => canonicalId(p)).join(',');
|
|
4286
4555
|
}
|
|
4287
4556
|
if (targetImpl.endAt) {
|
|
4288
|
-
|
|
4289
|
-
|
|
4557
|
+
str += '|ub:';
|
|
4558
|
+
str += targetImpl.endAt.inclusive ? 'a:' : 'b:';
|
|
4559
|
+
str += targetImpl.endAt.position.map(p => canonicalId(p)).join(',');
|
|
4290
4560
|
}
|
|
4291
|
-
targetImpl.memoizedCanonicalId =
|
|
4561
|
+
targetImpl.memoizedCanonicalId = str;
|
|
4292
4562
|
}
|
|
4293
4563
|
return targetImpl.memoizedCanonicalId;
|
|
4294
4564
|
}
|
|
@@ -4311,10 +4581,14 @@ function stringifyTarget(target) {
|
|
|
4311
4581
|
.join(', ')}]`;
|
|
4312
4582
|
}
|
|
4313
4583
|
if (target.startAt) {
|
|
4314
|
-
str += ', startAt: '
|
|
4584
|
+
str += ', startAt: ';
|
|
4585
|
+
str += target.startAt.inclusive ? 'b:' : 'a:';
|
|
4586
|
+
str += target.startAt.position.map(p => canonicalId(p)).join(',');
|
|
4315
4587
|
}
|
|
4316
4588
|
if (target.endAt) {
|
|
4317
|
-
str += ', endAt: '
|
|
4589
|
+
str += ', endAt: ';
|
|
4590
|
+
str += target.endAt.inclusive ? 'a:' : 'b:';
|
|
4591
|
+
str += target.endAt.position.map(p => canonicalId(p)).join(',');
|
|
4318
4592
|
}
|
|
4319
4593
|
return `Target(${str})`;
|
|
4320
4594
|
}
|
|
@@ -4349,7 +4623,7 @@ function targetEquals(left, right) {
|
|
|
4349
4623
|
}
|
|
4350
4624
|
return boundEquals(left.endAt, right.endAt);
|
|
4351
4625
|
}
|
|
4352
|
-
function
|
|
4626
|
+
function targetIsDocumentTarget(target) {
|
|
4353
4627
|
return (DocumentKey.isDocumentKey(target.path) &&
|
|
4354
4628
|
target.collectionGroup === null &&
|
|
4355
4629
|
target.filters.length === 0);
|
|
@@ -4552,17 +4826,11 @@ class ArrayContainsAnyFilter extends FieldFilter {
|
|
|
4552
4826
|
* just after the provided values.
|
|
4553
4827
|
*/
|
|
4554
4828
|
class Bound {
|
|
4555
|
-
constructor(position,
|
|
4829
|
+
constructor(position, inclusive) {
|
|
4556
4830
|
this.position = position;
|
|
4557
|
-
this.
|
|
4831
|
+
this.inclusive = inclusive;
|
|
4558
4832
|
}
|
|
4559
4833
|
}
|
|
4560
|
-
function canonifyBound(bound) {
|
|
4561
|
-
// TODO(b/29183165): Make this collision robust.
|
|
4562
|
-
return `${bound.before ? 'b' : 'a'}:${bound.position
|
|
4563
|
-
.map(p => canonicalId(p))
|
|
4564
|
-
.join(',')}`;
|
|
4565
|
-
}
|
|
4566
4834
|
/**
|
|
4567
4835
|
* An ordering on a field, in some Direction. Direction defaults to ASCENDING.
|
|
4568
4836
|
*/
|
|
@@ -4582,11 +4850,7 @@ function stringifyOrderBy(orderBy) {
|
|
|
4582
4850
|
function orderByEquals(left, right) {
|
|
4583
4851
|
return left.dir === right.dir && left.field.isEqual(right.field);
|
|
4584
4852
|
}
|
|
4585
|
-
|
|
4586
|
-
* Returns true if a document sorts before a bound using the provided sort
|
|
4587
|
-
* order.
|
|
4588
|
-
*/
|
|
4589
|
-
function sortsBeforeDocument(bound, orderBy, doc) {
|
|
4853
|
+
function boundCompareToDocument(bound, orderBy, doc) {
|
|
4590
4854
|
let comparison = 0;
|
|
4591
4855
|
for (let i = 0; i < bound.position.length; i++) {
|
|
4592
4856
|
const orderByComponent = orderBy[i];
|
|
@@ -4605,7 +4869,23 @@ function sortsBeforeDocument(bound, orderBy, doc) {
|
|
|
4605
4869
|
break;
|
|
4606
4870
|
}
|
|
4607
4871
|
}
|
|
4608
|
-
return
|
|
4872
|
+
return comparison;
|
|
4873
|
+
}
|
|
4874
|
+
/**
|
|
4875
|
+
* Returns true if a document sorts after a bound using the provided sort
|
|
4876
|
+
* order.
|
|
4877
|
+
*/
|
|
4878
|
+
function boundSortsAfterDocument(bound, orderBy, doc) {
|
|
4879
|
+
const comparison = boundCompareToDocument(bound, orderBy, doc);
|
|
4880
|
+
return bound.inclusive ? comparison >= 0 : comparison > 0;
|
|
4881
|
+
}
|
|
4882
|
+
/**
|
|
4883
|
+
* Returns true if a document sorts before a bound using the provided sort
|
|
4884
|
+
* order.
|
|
4885
|
+
*/
|
|
4886
|
+
function boundSortsBeforeDocument(bound, orderBy, doc) {
|
|
4887
|
+
const comparison = boundCompareToDocument(bound, orderBy, doc);
|
|
4888
|
+
return bound.inclusive ? comparison <= 0 : comparison < 0;
|
|
4609
4889
|
}
|
|
4610
4890
|
function boundEquals(left, right) {
|
|
4611
4891
|
if (left === null) {
|
|
@@ -4614,7 +4894,7 @@ function boundEquals(left, right) {
|
|
|
4614
4894
|
else if (right === null) {
|
|
4615
4895
|
return false;
|
|
4616
4896
|
}
|
|
4617
|
-
if (left.
|
|
4897
|
+
if (left.inclusive !== right.inclusive ||
|
|
4618
4898
|
left.position.length !== right.position.length) {
|
|
4619
4899
|
return false;
|
|
4620
4900
|
}
|
|
@@ -4818,10 +5098,10 @@ function queryToTarget(query) {
|
|
|
4818
5098
|
}
|
|
4819
5099
|
// We need to swap the cursors to match the now-flipped query ordering.
|
|
4820
5100
|
const startAt = queryImpl.endAt
|
|
4821
|
-
? new Bound(queryImpl.endAt.position, !queryImpl.endAt.
|
|
5101
|
+
? new Bound(queryImpl.endAt.position, !queryImpl.endAt.inclusive)
|
|
4822
5102
|
: null;
|
|
4823
5103
|
const endAt = queryImpl.startAt
|
|
4824
|
-
? new Bound(queryImpl.startAt.position, !queryImpl.startAt.
|
|
5104
|
+
? new Bound(queryImpl.startAt.position, !queryImpl.startAt.inclusive)
|
|
4825
5105
|
: null;
|
|
4826
5106
|
// Now return as a LimitType.First query.
|
|
4827
5107
|
queryImpl.memoizedTarget = newTarget(queryImpl.path, queryImpl.collectionGroup, orderBys, queryImpl.filters, queryImpl.limit, startAt, endAt);
|
|
@@ -4909,11 +5189,11 @@ function queryMatchesFilters(query, doc) {
|
|
|
4909
5189
|
/** Makes sure a document is within the bounds, if provided. */
|
|
4910
5190
|
function queryMatchesBounds(query, doc) {
|
|
4911
5191
|
if (query.startAt &&
|
|
4912
|
-
!
|
|
5192
|
+
!boundSortsBeforeDocument(query.startAt, queryOrderBy(query), doc)) {
|
|
4913
5193
|
return false;
|
|
4914
5194
|
}
|
|
4915
5195
|
if (query.endAt &&
|
|
4916
|
-
|
|
5196
|
+
!boundSortsAfterDocument(query.endAt, queryOrderBy(query), doc)) {
|
|
4917
5197
|
return false;
|
|
4918
5198
|
}
|
|
4919
5199
|
return true;
|
|
@@ -6994,7 +7274,7 @@ class WatchChangeAggregator {
|
|
|
6994
7274
|
const targetData = this.targetDataForActiveTarget(targetId);
|
|
6995
7275
|
if (targetData) {
|
|
6996
7276
|
const target = targetData.target;
|
|
6997
|
-
if (
|
|
7277
|
+
if (targetIsDocumentTarget(target)) {
|
|
6998
7278
|
if (expectedCount === 0) {
|
|
6999
7279
|
// The existence filter told us the document does not exist. We deduce
|
|
7000
7280
|
// that this document does not exist and apply a deleted document to
|
|
@@ -7029,7 +7309,7 @@ class WatchChangeAggregator {
|
|
|
7029
7309
|
this.targetStates.forEach((targetState, targetId) => {
|
|
7030
7310
|
const targetData = this.targetDataForActiveTarget(targetId);
|
|
7031
7311
|
if (targetData) {
|
|
7032
|
-
if (targetState.current &&
|
|
7312
|
+
if (targetState.current && targetIsDocumentTarget(targetData.target)) {
|
|
7033
7313
|
// Document queries for document that don't exist can produce an empty
|
|
7034
7314
|
// result set. To update our local cache, we synthesize a document
|
|
7035
7315
|
// delete if we have not previously received the document. This
|
|
@@ -7072,6 +7352,7 @@ class WatchChangeAggregator {
|
|
|
7072
7352
|
resolvedLimboDocuments = resolvedLimboDocuments.add(key);
|
|
7073
7353
|
}
|
|
7074
7354
|
});
|
|
7355
|
+
this.pendingDocumentUpdates.forEach((_, doc) => doc.setReadTime(snapshotVersion));
|
|
7075
7356
|
const remoteEvent = new RemoteEvent(snapshotVersion, targetChanges, this.pendingTargetResets, this.pendingDocumentUpdates, resolvedLimboDocuments);
|
|
7076
7357
|
this.pendingDocumentUpdates = mutableDocumentMap();
|
|
7077
7358
|
this.pendingDocumentTargetMapping = documentTargetMap();
|
|
@@ -7791,10 +8072,10 @@ function toQueryTarget(serializer, target) {
|
|
|
7791
8072
|
result.structuredQuery.limit = limit;
|
|
7792
8073
|
}
|
|
7793
8074
|
if (target.startAt) {
|
|
7794
|
-
result.structuredQuery.startAt =
|
|
8075
|
+
result.structuredQuery.startAt = toStartAtCursor(target.startAt);
|
|
7795
8076
|
}
|
|
7796
8077
|
if (target.endAt) {
|
|
7797
|
-
result.structuredQuery.endAt =
|
|
8078
|
+
result.structuredQuery.endAt = toEndAtCursor(target.endAt);
|
|
7798
8079
|
}
|
|
7799
8080
|
return result;
|
|
7800
8081
|
}
|
|
@@ -7827,11 +8108,11 @@ function convertQueryTargetToQuery(target) {
|
|
|
7827
8108
|
}
|
|
7828
8109
|
let startAt = null;
|
|
7829
8110
|
if (query.startAt) {
|
|
7830
|
-
startAt =
|
|
8111
|
+
startAt = fromStartAtCursor(query.startAt);
|
|
7831
8112
|
}
|
|
7832
8113
|
let endAt = null;
|
|
7833
8114
|
if (query.endAt) {
|
|
7834
|
-
endAt =
|
|
8115
|
+
endAt = fromEndAtCursor(query.endAt);
|
|
7835
8116
|
}
|
|
7836
8117
|
return newQuery(path, collectionGroup, orderBy, filterBy, limit, "F" /* First */, startAt, endAt);
|
|
7837
8118
|
}
|
|
@@ -7864,7 +8145,7 @@ function toLabel(serializer, purpose) {
|
|
|
7864
8145
|
function toTarget(serializer, targetData) {
|
|
7865
8146
|
let result;
|
|
7866
8147
|
const target = targetData.target;
|
|
7867
|
-
if (
|
|
8148
|
+
if (targetIsDocumentTarget(target)) {
|
|
7868
8149
|
result = { documents: toDocumentsTarget(serializer, target) };
|
|
7869
8150
|
}
|
|
7870
8151
|
else {
|
|
@@ -7922,16 +8203,27 @@ function toOrder(orderBys) {
|
|
|
7922
8203
|
function fromOrder(orderBys) {
|
|
7923
8204
|
return orderBys.map(order => fromPropertyOrder(order));
|
|
7924
8205
|
}
|
|
7925
|
-
function
|
|
8206
|
+
function toStartAtCursor(cursor) {
|
|
8207
|
+
return {
|
|
8208
|
+
before: cursor.inclusive,
|
|
8209
|
+
values: cursor.position
|
|
8210
|
+
};
|
|
8211
|
+
}
|
|
8212
|
+
function toEndAtCursor(cursor) {
|
|
7926
8213
|
return {
|
|
7927
|
-
before: cursor.
|
|
8214
|
+
before: !cursor.inclusive,
|
|
7928
8215
|
values: cursor.position
|
|
7929
8216
|
};
|
|
7930
8217
|
}
|
|
7931
|
-
function
|
|
7932
|
-
const
|
|
8218
|
+
function fromStartAtCursor(cursor) {
|
|
8219
|
+
const inclusive = !!cursor.before;
|
|
7933
8220
|
const position = cursor.values || [];
|
|
7934
|
-
return new Bound(position,
|
|
8221
|
+
return new Bound(position, inclusive);
|
|
8222
|
+
}
|
|
8223
|
+
function fromEndAtCursor(cursor) {
|
|
8224
|
+
const inclusive = !cursor.before;
|
|
8225
|
+
const position = cursor.values || [];
|
|
8226
|
+
return new Bound(position, inclusive);
|
|
7935
8227
|
}
|
|
7936
8228
|
// visible for testing
|
|
7937
8229
|
function toDirection(dir) {
|
|
@@ -8192,29 +8484,34 @@ class LocalSerializer {
|
|
|
8192
8484
|
}
|
|
8193
8485
|
/** Decodes a remote document from storage locally to a Document. */
|
|
8194
8486
|
function fromDbRemoteDocument(localSerializer, remoteDoc) {
|
|
8487
|
+
let doc;
|
|
8195
8488
|
if (remoteDoc.document) {
|
|
8196
|
-
|
|
8489
|
+
doc = fromDocument(localSerializer.remoteSerializer, remoteDoc.document, !!remoteDoc.hasCommittedMutations);
|
|
8197
8490
|
}
|
|
8198
8491
|
else if (remoteDoc.noDocument) {
|
|
8199
8492
|
const key = DocumentKey.fromSegments(remoteDoc.noDocument.path);
|
|
8200
8493
|
const version = fromDbTimestamp(remoteDoc.noDocument.readTime);
|
|
8201
|
-
|
|
8202
|
-
|
|
8203
|
-
|
|
8204
|
-
|
|
8494
|
+
doc = MutableDocument.newNoDocument(key, version);
|
|
8495
|
+
if (remoteDoc.hasCommittedMutations) {
|
|
8496
|
+
doc.setHasCommittedMutations();
|
|
8497
|
+
}
|
|
8205
8498
|
}
|
|
8206
8499
|
else if (remoteDoc.unknownDocument) {
|
|
8207
8500
|
const key = DocumentKey.fromSegments(remoteDoc.unknownDocument.path);
|
|
8208
8501
|
const version = fromDbTimestamp(remoteDoc.unknownDocument.version);
|
|
8209
|
-
|
|
8502
|
+
doc = MutableDocument.newUnknownDocument(key, version);
|
|
8210
8503
|
}
|
|
8211
8504
|
else {
|
|
8212
8505
|
return fail();
|
|
8213
8506
|
}
|
|
8507
|
+
if (remoteDoc.readTime) {
|
|
8508
|
+
doc.setReadTime(fromDbTimestampKey(remoteDoc.readTime));
|
|
8509
|
+
}
|
|
8510
|
+
return doc;
|
|
8214
8511
|
}
|
|
8215
8512
|
/** Encodes a document for storage locally. */
|
|
8216
|
-
function toDbRemoteDocument(localSerializer, document
|
|
8217
|
-
const dbReadTime = toDbTimestampKey(readTime);
|
|
8513
|
+
function toDbRemoteDocument(localSerializer, document) {
|
|
8514
|
+
const dbReadTime = toDbTimestampKey(document.readTime);
|
|
8218
8515
|
const parentPath = document.key.path.popLast().toArray();
|
|
8219
8516
|
if (document.isFoundDocument()) {
|
|
8220
8517
|
const doc = toDocument(localSerializer.remoteSerializer, document);
|
|
@@ -8225,10 +8522,10 @@ function toDbRemoteDocument(localSerializer, document, readTime) {
|
|
|
8225
8522
|
}
|
|
8226
8523
|
else if (document.isNoDocument()) {
|
|
8227
8524
|
const path = document.key.path.toArray();
|
|
8228
|
-
const
|
|
8525
|
+
const version = toDbTimestamp(document.version);
|
|
8229
8526
|
const hasCommittedMutations = document.hasCommittedMutations;
|
|
8230
8527
|
return new DbRemoteDocument(
|
|
8231
|
-
/* unknownDocument= */ null, new DbNoDocument(path,
|
|
8528
|
+
/* unknownDocument= */ null, new DbNoDocument(path, version),
|
|
8232
8529
|
/* document= */ null, hasCommittedMutations, dbReadTime, parentPath);
|
|
8233
8530
|
}
|
|
8234
8531
|
else if (document.isUnknownDocument()) {
|
|
@@ -8309,7 +8606,7 @@ function toDbTarget(localSerializer, targetData) {
|
|
|
8309
8606
|
const dbTimestamp = toDbTimestamp(targetData.snapshotVersion);
|
|
8310
8607
|
const dbLastLimboFreeTimestamp = toDbTimestamp(targetData.lastLimboFreeSnapshotVersion);
|
|
8311
8608
|
let queryProto;
|
|
8312
|
-
if (
|
|
8609
|
+
if (targetIsDocumentTarget(targetData.target)) {
|
|
8313
8610
|
queryProto = toDocumentsTarget(localSerializer.remoteSerializer, targetData.target);
|
|
8314
8611
|
}
|
|
8315
8612
|
else {
|
|
@@ -8479,6 +8776,38 @@ class MemoryIndexManager {
|
|
|
8479
8776
|
getCollectionParents(transaction, collectionId) {
|
|
8480
8777
|
return PersistencePromise.resolve(this.collectionParentIndex.getEntries(collectionId));
|
|
8481
8778
|
}
|
|
8779
|
+
addFieldIndex(transaction, index) {
|
|
8780
|
+
// Field indices are not supported with memory persistence.
|
|
8781
|
+
return PersistencePromise.resolve();
|
|
8782
|
+
}
|
|
8783
|
+
deleteFieldIndex(transaction, index) {
|
|
8784
|
+
// Field indices are not supported with memory persistence.
|
|
8785
|
+
return PersistencePromise.resolve();
|
|
8786
|
+
}
|
|
8787
|
+
getDocumentsMatchingTarget(transaction, fieldIndex, target) {
|
|
8788
|
+
// Field indices are not supported with memory persistence.
|
|
8789
|
+
return PersistencePromise.resolve(documentKeySet());
|
|
8790
|
+
}
|
|
8791
|
+
getFieldIndex(transaction, target) {
|
|
8792
|
+
// Field indices are not supported with memory persistence.
|
|
8793
|
+
return PersistencePromise.resolve(null);
|
|
8794
|
+
}
|
|
8795
|
+
getFieldIndexes(transaction, collectionGroup) {
|
|
8796
|
+
// Field indices are not supported with memory persistence.
|
|
8797
|
+
return PersistencePromise.resolve([]);
|
|
8798
|
+
}
|
|
8799
|
+
getNextCollectionGroupToUpdate(transaction) {
|
|
8800
|
+
// Field indices are not supported with memory persistence.
|
|
8801
|
+
return PersistencePromise.resolve(null);
|
|
8802
|
+
}
|
|
8803
|
+
updateCollectionGroup(transaction, collectionGroup, offset) {
|
|
8804
|
+
// Field indices are not supported with memory persistence.
|
|
8805
|
+
return PersistencePromise.resolve();
|
|
8806
|
+
}
|
|
8807
|
+
updateIndexEntries(transaction, documents) {
|
|
8808
|
+
// Field indices are not supported with memory persistence.
|
|
8809
|
+
return PersistencePromise.resolve();
|
|
8810
|
+
}
|
|
8482
8811
|
}
|
|
8483
8812
|
/**
|
|
8484
8813
|
* Internal implementation of the collection-parent index exposed by MemoryIndexManager.
|
|
@@ -8587,6 +8916,38 @@ class IndexedDbIndexManager {
|
|
|
8587
8916
|
return parentPaths;
|
|
8588
8917
|
});
|
|
8589
8918
|
}
|
|
8919
|
+
addFieldIndex(transaction, index) {
|
|
8920
|
+
// TODO(indexing): Implement
|
|
8921
|
+
return PersistencePromise.resolve();
|
|
8922
|
+
}
|
|
8923
|
+
deleteFieldIndex(transaction, index) {
|
|
8924
|
+
// TODO(indexing): Implement
|
|
8925
|
+
return PersistencePromise.resolve();
|
|
8926
|
+
}
|
|
8927
|
+
getDocumentsMatchingTarget(transaction, fieldIndex, target) {
|
|
8928
|
+
// TODO(indexing): Implement
|
|
8929
|
+
return PersistencePromise.resolve(documentKeySet());
|
|
8930
|
+
}
|
|
8931
|
+
getFieldIndex(transaction, target) {
|
|
8932
|
+
// TODO(indexing): Implement
|
|
8933
|
+
return PersistencePromise.resolve(null);
|
|
8934
|
+
}
|
|
8935
|
+
getFieldIndexes(transaction, collectionGroup) {
|
|
8936
|
+
// TODO(indexing): Implement
|
|
8937
|
+
return PersistencePromise.resolve([]);
|
|
8938
|
+
}
|
|
8939
|
+
getNextCollectionGroupToUpdate(transaction) {
|
|
8940
|
+
// TODO(indexing): Implement
|
|
8941
|
+
return PersistencePromise.resolve(null);
|
|
8942
|
+
}
|
|
8943
|
+
updateCollectionGroup(transaction, collectionGroup, offset) {
|
|
8944
|
+
// TODO(indexing): Implement
|
|
8945
|
+
return PersistencePromise.resolve();
|
|
8946
|
+
}
|
|
8947
|
+
updateIndexEntries(transaction, documents) {
|
|
8948
|
+
// TODO(indexing): Implement
|
|
8949
|
+
return PersistencePromise.resolve();
|
|
8950
|
+
}
|
|
8590
8951
|
}
|
|
8591
8952
|
/**
|
|
8592
8953
|
* Helper to get a typed SimpleDbStore for the collectionParents
|
|
@@ -9757,7 +10118,7 @@ class IndexedDbLruDelegateImpl {
|
|
|
9757
10118
|
// Our size accounting requires us to read all documents before
|
|
9758
10119
|
// removing them.
|
|
9759
10120
|
return changeBuffer.getEntry(txn, docKey).next(() => {
|
|
9760
|
-
changeBuffer.removeEntry(docKey);
|
|
10121
|
+
changeBuffer.removeEntry(docKey, SnapshotVersion.min());
|
|
9761
10122
|
return documentTargetStore(txn).delete(sentinelKey$1(docKey));
|
|
9762
10123
|
});
|
|
9763
10124
|
}
|
|
@@ -9970,27 +10331,19 @@ class ObjectMap {
|
|
|
9970
10331
|
*/
|
|
9971
10332
|
class RemoteDocumentChangeBuffer {
|
|
9972
10333
|
constructor() {
|
|
9973
|
-
// A mapping of document key to the new cache entry that should be written
|
|
9974
|
-
// existing cache entry should be removed).
|
|
10334
|
+
// A mapping of document key to the new cache entry that should be written.
|
|
9975
10335
|
this.changes = new ObjectMap(key => key.toString(), (l, r) => l.isEqual(r));
|
|
9976
10336
|
this.changesApplied = false;
|
|
9977
10337
|
}
|
|
9978
|
-
getReadTime(key) {
|
|
9979
|
-
const change = this.changes.get(key);
|
|
9980
|
-
if (change) {
|
|
9981
|
-
return change.readTime;
|
|
9982
|
-
}
|
|
9983
|
-
return SnapshotVersion.min();
|
|
9984
|
-
}
|
|
9985
10338
|
/**
|
|
9986
10339
|
* Buffers a `RemoteDocumentCache.addEntry()` call.
|
|
9987
10340
|
*
|
|
9988
10341
|
* You can only modify documents that have already been retrieved via
|
|
9989
10342
|
* `getEntry()/getEntries()` (enforced via IndexedDbs `apply()`).
|
|
9990
10343
|
*/
|
|
9991
|
-
addEntry(document
|
|
10344
|
+
addEntry(document) {
|
|
9992
10345
|
this.assertNotApplied();
|
|
9993
|
-
this.changes.set(document.key,
|
|
10346
|
+
this.changes.set(document.key, document);
|
|
9994
10347
|
}
|
|
9995
10348
|
/**
|
|
9996
10349
|
* Buffers a `RemoteDocumentCache.removeEntry()` call.
|
|
@@ -9998,12 +10351,9 @@ class RemoteDocumentChangeBuffer {
|
|
|
9998
10351
|
* You can only remove documents that have already been retrieved via
|
|
9999
10352
|
* `getEntry()/getEntries()` (enforced via IndexedDbs `apply()`).
|
|
10000
10353
|
*/
|
|
10001
|
-
removeEntry(key, readTime
|
|
10354
|
+
removeEntry(key, readTime) {
|
|
10002
10355
|
this.assertNotApplied();
|
|
10003
|
-
this.changes.set(key,
|
|
10004
|
-
document: MutableDocument.newInvalidDocument(key),
|
|
10005
|
-
readTime
|
|
10006
|
-
});
|
|
10356
|
+
this.changes.set(key, MutableDocument.newInvalidDocument(key).setReadTime(readTime));
|
|
10007
10357
|
}
|
|
10008
10358
|
/**
|
|
10009
10359
|
* Looks up an entry in the cache. The buffered changes will first be checked,
|
|
@@ -10020,7 +10370,7 @@ class RemoteDocumentChangeBuffer {
|
|
|
10020
10370
|
this.assertNotApplied();
|
|
10021
10371
|
const bufferedEntry = this.changes.get(documentKey);
|
|
10022
10372
|
if (bufferedEntry !== undefined) {
|
|
10023
|
-
return PersistencePromise.resolve(bufferedEntry
|
|
10373
|
+
return PersistencePromise.resolve(bufferedEntry);
|
|
10024
10374
|
}
|
|
10025
10375
|
else {
|
|
10026
10376
|
return this.getFromCache(transaction, documentKey);
|
|
@@ -10231,7 +10581,7 @@ class IndexedDbRemoteDocumentCacheImpl {
|
|
|
10231
10581
|
if (key.length !== immediateChildrenPathLength) {
|
|
10232
10582
|
return;
|
|
10233
10583
|
}
|
|
10234
|
-
const document =
|
|
10584
|
+
const document = this.maybeDecodeDocument(DocumentKey.fromSegments(key), dbRemoteDoc);
|
|
10235
10585
|
if (!query.path.isPrefixOf(document.key.path)) {
|
|
10236
10586
|
control.done();
|
|
10237
10587
|
}
|
|
@@ -10259,8 +10609,8 @@ class IndexedDbRemoteDocumentCacheImpl {
|
|
|
10259
10609
|
return documentGlobalStore(txn).put(DbRemoteDocumentGlobal.key, metadata);
|
|
10260
10610
|
}
|
|
10261
10611
|
/**
|
|
10262
|
-
* Decodes `
|
|
10263
|
-
* corresponds to the format used for sentinel deletes).
|
|
10612
|
+
* Decodes `dbRemoteDoc` and returns the document (or an invalid document if
|
|
10613
|
+
* the document corresponds to the format used for sentinel deletes).
|
|
10264
10614
|
*/
|
|
10265
10615
|
maybeDecodeDocument(documentKey, dbRemoteDoc) {
|
|
10266
10616
|
if (dbRemoteDoc) {
|
|
@@ -10354,8 +10704,8 @@ class IndexedDbRemoteDocumentChangeBuffer extends RemoteDocumentChangeBuffer {
|
|
|
10354
10704
|
let collectionParents = new SortedSet((l, r) => primitiveComparator(l.canonicalString(), r.canonicalString()));
|
|
10355
10705
|
this.changes.forEach((key, documentChange) => {
|
|
10356
10706
|
const previousSize = this.documentSizes.get(key);
|
|
10357
|
-
if (documentChange.
|
|
10358
|
-
const doc = toDbRemoteDocument(this.documentCache.serializer, documentChange
|
|
10707
|
+
if (documentChange.isValidDocument()) {
|
|
10708
|
+
const doc = toDbRemoteDocument(this.documentCache.serializer, documentChange);
|
|
10359
10709
|
collectionParents = collectionParents.add(key.path.popLast());
|
|
10360
10710
|
const size = dbDocumentSize(doc);
|
|
10361
10711
|
sizeDelta += size - previousSize;
|
|
@@ -10368,7 +10718,7 @@ class IndexedDbRemoteDocumentChangeBuffer extends RemoteDocumentChangeBuffer {
|
|
|
10368
10718
|
// RemoteDocumentCache. This entry is represented by a NoDocument
|
|
10369
10719
|
// with a version of 0 and ignored by `maybeDecodeDocument()` but
|
|
10370
10720
|
// preserved in `getNewDocumentChanges()`.
|
|
10371
|
-
const deletedDoc = toDbRemoteDocument(this.documentCache.serializer,
|
|
10721
|
+
const deletedDoc = toDbRemoteDocument(this.documentCache.serializer, documentChange.convertToNoDocument(SnapshotVersion.min()));
|
|
10372
10722
|
promises.push(this.documentCache.addEntry(transaction, key, deletedDoc));
|
|
10373
10723
|
}
|
|
10374
10724
|
else {
|
|
@@ -10449,9 +10799,6 @@ class SchemaConverter {
|
|
|
10449
10799
|
* and local feature development.
|
|
10450
10800
|
*/
|
|
10451
10801
|
createOrUpgrade(db, txn, fromVersion, toVersion) {
|
|
10452
|
-
hardAssert(fromVersion < toVersion &&
|
|
10453
|
-
fromVersion >= 0 &&
|
|
10454
|
-
toVersion <= SCHEMA_VERSION);
|
|
10455
10802
|
const simpleDbTransaction = new SimpleDbTransaction('createOrUpgrade', txn);
|
|
10456
10803
|
if (fromVersion < 1 && toVersion >= 1) {
|
|
10457
10804
|
createPrimaryClientStore(db);
|
|
@@ -10518,6 +10865,11 @@ class SchemaConverter {
|
|
|
10518
10865
|
createNamedQueriesStore(db);
|
|
10519
10866
|
});
|
|
10520
10867
|
}
|
|
10868
|
+
if (fromVersion < 12 && toVersion >= 12) {
|
|
10869
|
+
p = p.next(() => {
|
|
10870
|
+
createFieldIndex(db);
|
|
10871
|
+
});
|
|
10872
|
+
}
|
|
10521
10873
|
return p;
|
|
10522
10874
|
}
|
|
10523
10875
|
addDocumentGlobal(txn) {
|
|
@@ -10724,6 +11076,17 @@ function createNamedQueriesStore(db) {
|
|
|
10724
11076
|
db.createObjectStore(DbNamedQuery.store, {
|
|
10725
11077
|
keyPath: DbNamedQuery.keyPath
|
|
10726
11078
|
});
|
|
11079
|
+
}
|
|
11080
|
+
function createFieldIndex(db) {
|
|
11081
|
+
db.createObjectStore(DbIndexConfiguration.store, {
|
|
11082
|
+
keyPath: DbIndexConfiguration.keyPath
|
|
11083
|
+
});
|
|
11084
|
+
db.createObjectStore(DbIndexState.store, {
|
|
11085
|
+
keyPath: DbIndexState.keyPath
|
|
11086
|
+
});
|
|
11087
|
+
db.createObjectStore(DbIndexEntries.store, {
|
|
11088
|
+
keyPath: DbIndexEntries.keyPath
|
|
11089
|
+
});
|
|
10727
11090
|
}
|
|
10728
11091
|
|
|
10729
11092
|
/**
|
|
@@ -11955,14 +12318,14 @@ function localStoreApplyRemoteEventToLocalCache(localStore, remoteEvent) {
|
|
|
11955
12318
|
}
|
|
11956
12319
|
});
|
|
11957
12320
|
let changedDocs = mutableDocumentMap();
|
|
11958
|
-
remoteEvent.documentUpdates.forEach(
|
|
12321
|
+
remoteEvent.documentUpdates.forEach(key => {
|
|
11959
12322
|
if (remoteEvent.resolvedLimboDocuments.has(key)) {
|
|
11960
12323
|
promises.push(localStoreImpl.persistence.referenceDelegate.updateLimboDocument(txn, key));
|
|
11961
12324
|
}
|
|
11962
12325
|
});
|
|
11963
12326
|
// Each loop iteration only affects its "own" doc, so it's safe to get all the remote
|
|
11964
12327
|
// documents in advance in a single call.
|
|
11965
|
-
promises.push(populateDocumentChangeBuffer(txn, documentBuffer, remoteEvent.documentUpdates
|
|
12328
|
+
promises.push(populateDocumentChangeBuffer(txn, documentBuffer, remoteEvent.documentUpdates).next(result => {
|
|
11966
12329
|
changedDocs = result;
|
|
11967
12330
|
}));
|
|
11968
12331
|
// HACK: The only reason we allow a null snapshot version is so that we
|
|
@@ -12003,17 +12366,13 @@ function localStoreApplyRemoteEventToLocalCache(localStore, remoteEvent) {
|
|
|
12003
12366
|
* Note: this function will use `documentVersions` if it is defined;
|
|
12004
12367
|
* when it is not defined, resorts to `globalVersion`.
|
|
12005
12368
|
*/
|
|
12006
|
-
function populateDocumentChangeBuffer(txn, documentBuffer, documents
|
|
12007
|
-
// TODO(wuandy): We could add `readTime` to MaybeDocument instead to remove
|
|
12008
|
-
// this parameter.
|
|
12009
|
-
documentVersions) {
|
|
12369
|
+
function populateDocumentChangeBuffer(txn, documentBuffer, documents) {
|
|
12010
12370
|
let updatedKeys = documentKeySet();
|
|
12011
12371
|
documents.forEach(k => (updatedKeys = updatedKeys.add(k)));
|
|
12012
12372
|
return documentBuffer.getEntries(txn, updatedKeys).next(existingDocs => {
|
|
12013
12373
|
let changedDocs = mutableDocumentMap();
|
|
12014
12374
|
documents.forEach((key, doc) => {
|
|
12015
12375
|
const existingDoc = existingDocs.get(key);
|
|
12016
|
-
const docReadTime = (documentVersions === null || documentVersions === void 0 ? void 0 : documentVersions.get(key)) || globalVersion;
|
|
12017
12376
|
// Note: The order of the steps below is important, since we want
|
|
12018
12377
|
// to ensure that rejected limbo resolutions (which fabricate
|
|
12019
12378
|
// NoDocuments with SnapshotVersion.min()) never add documents to
|
|
@@ -12022,14 +12381,14 @@ documentVersions) {
|
|
|
12022
12381
|
// NoDocuments with SnapshotVersion.min() are used in manufactured
|
|
12023
12382
|
// events. We remove these documents from cache since we lost
|
|
12024
12383
|
// access.
|
|
12025
|
-
documentBuffer.removeEntry(key,
|
|
12384
|
+
documentBuffer.removeEntry(key, doc.readTime);
|
|
12026
12385
|
changedDocs = changedDocs.insert(key, doc);
|
|
12027
12386
|
}
|
|
12028
12387
|
else if (!existingDoc.isValidDocument() ||
|
|
12029
12388
|
doc.version.compareTo(existingDoc.version) > 0 ||
|
|
12030
12389
|
(doc.version.compareTo(existingDoc.version) === 0 &&
|
|
12031
12390
|
existingDoc.hasPendingWrites)) {
|
|
12032
|
-
documentBuffer.addEntry(doc
|
|
12391
|
+
documentBuffer.addEntry(doc);
|
|
12033
12392
|
changedDocs = changedDocs.insert(key, doc);
|
|
12034
12393
|
}
|
|
12035
12394
|
else {
|
|
@@ -12283,7 +12642,8 @@ function applyWriteToRemoteDocuments(localStoreImpl, txn, batchResult, documentB
|
|
|
12283
12642
|
// We use the commitVersion as the readTime rather than the
|
|
12284
12643
|
// document's updateTime since the updateTime is not advanced
|
|
12285
12644
|
// for updates that do not modify the underlying document.
|
|
12286
|
-
|
|
12645
|
+
doc.setReadTime(batchResult.commitVersion);
|
|
12646
|
+
documentBuffer.addEntry(doc);
|
|
12287
12647
|
}
|
|
12288
12648
|
}
|
|
12289
12649
|
});
|
|
@@ -12384,14 +12744,14 @@ async function localStoreApplyBundledDocuments(localStore, bundleConverter, docu
|
|
|
12384
12744
|
const localStoreImpl = debugCast(localStore);
|
|
12385
12745
|
let documentKeys = documentKeySet();
|
|
12386
12746
|
let documentMap = mutableDocumentMap();
|
|
12387
|
-
let versionMap = documentVersionMap();
|
|
12388
12747
|
for (const bundleDoc of documents) {
|
|
12389
12748
|
const documentKey = bundleConverter.toDocumentKey(bundleDoc.metadata.name);
|
|
12390
12749
|
if (bundleDoc.document) {
|
|
12391
12750
|
documentKeys = documentKeys.add(documentKey);
|
|
12392
12751
|
}
|
|
12393
|
-
|
|
12394
|
-
|
|
12752
|
+
const doc = bundleConverter.toMutableDocument(bundleDoc);
|
|
12753
|
+
doc.setReadTime(bundleConverter.toSnapshotVersion(bundleDoc.metadata.readTime));
|
|
12754
|
+
documentMap = documentMap.insert(documentKey, doc);
|
|
12395
12755
|
}
|
|
12396
12756
|
const documentBuffer = localStoreImpl.remoteDocuments.newChangeBuffer({
|
|
12397
12757
|
trackRemovals: true // Make sure document removals show up in `getNewDocumentChanges()`
|
|
@@ -12400,7 +12760,7 @@ async function localStoreApplyBundledDocuments(localStore, bundleConverter, docu
|
|
|
12400
12760
|
// they will not get garbage collected right away.
|
|
12401
12761
|
const umbrellaTargetData = await localStoreAllocateTarget(localStoreImpl, umbrellaTarget(bundleName));
|
|
12402
12762
|
return localStoreImpl.persistence.runTransaction('Apply bundle documents', 'readwrite', txn => {
|
|
12403
|
-
return populateDocumentChangeBuffer(txn, documentBuffer, documentMap
|
|
12763
|
+
return populateDocumentChangeBuffer(txn, documentBuffer, documentMap)
|
|
12404
12764
|
.next(changedDocs => {
|
|
12405
12765
|
documentBuffer.apply(txn);
|
|
12406
12766
|
return changedDocs;
|
|
@@ -12881,15 +13241,14 @@ class MemoryRemoteDocumentCacheImpl {
|
|
|
12881
13241
|
* All calls of `addEntry` are required to go through the RemoteDocumentChangeBuffer
|
|
12882
13242
|
* returned by `newChangeBuffer()`.
|
|
12883
13243
|
*/
|
|
12884
|
-
addEntry(transaction, doc
|
|
13244
|
+
addEntry(transaction, doc) {
|
|
12885
13245
|
const key = doc.key;
|
|
12886
13246
|
const entry = this.docs.get(key);
|
|
12887
13247
|
const previousSize = entry ? entry.size : 0;
|
|
12888
13248
|
const currentSize = this.sizer(doc);
|
|
12889
13249
|
this.docs = this.docs.insert(key, {
|
|
12890
13250
|
document: doc.mutableCopy(),
|
|
12891
|
-
size: currentSize
|
|
12892
|
-
readTime
|
|
13251
|
+
size: currentSize
|
|
12893
13252
|
});
|
|
12894
13253
|
this.size += currentSize - previousSize;
|
|
12895
13254
|
return this.indexManager.addToCollectionParentIndex(transaction, key.path.popLast());
|
|
@@ -12930,11 +13289,11 @@ class MemoryRemoteDocumentCacheImpl {
|
|
|
12930
13289
|
const prefix = new DocumentKey(query.path.child(''));
|
|
12931
13290
|
const iterator = this.docs.getIteratorFrom(prefix);
|
|
12932
13291
|
while (iterator.hasNext()) {
|
|
12933
|
-
const { key, value: { document
|
|
13292
|
+
const { key, value: { document } } = iterator.getNext();
|
|
12934
13293
|
if (!query.path.isPrefixOf(key.path)) {
|
|
12935
13294
|
break;
|
|
12936
13295
|
}
|
|
12937
|
-
if (readTime.compareTo(sinceReadTime) <= 0) {
|
|
13296
|
+
if (document.readTime.compareTo(sinceReadTime) <= 0) {
|
|
12938
13297
|
continue;
|
|
12939
13298
|
}
|
|
12940
13299
|
if (!queryMatches(query, document)) {
|
|
@@ -12978,8 +13337,8 @@ class MemoryRemoteDocumentChangeBuffer extends RemoteDocumentChangeBuffer {
|
|
|
12978
13337
|
applyChanges(transaction) {
|
|
12979
13338
|
const promises = [];
|
|
12980
13339
|
this.changes.forEach((key, doc) => {
|
|
12981
|
-
if (doc.
|
|
12982
|
-
promises.push(this.documentCache.addEntry(transaction, doc
|
|
13340
|
+
if (doc.isValidDocument()) {
|
|
13341
|
+
promises.push(this.documentCache.addEntry(transaction, doc));
|
|
12983
13342
|
}
|
|
12984
13343
|
else {
|
|
12985
13344
|
this.documentCache.removeEntry(key);
|
|
@@ -13292,7 +13651,7 @@ class MemoryEagerDelegate {
|
|
|
13292
13651
|
const key = DocumentKey.fromPath(path);
|
|
13293
13652
|
return this.isReferenced(txn, key).next(isReferenced => {
|
|
13294
13653
|
if (!isReferenced) {
|
|
13295
|
-
changeBuffer.removeEntry(key);
|
|
13654
|
+
changeBuffer.removeEntry(key, SnapshotVersion.min());
|
|
13296
13655
|
}
|
|
13297
13656
|
});
|
|
13298
13657
|
}).next(() => {
|
|
@@ -17072,6 +17431,40 @@ const nested = {
|
|
|
17072
17431
|
id: 2
|
|
17073
17432
|
}
|
|
17074
17433
|
}
|
|
17434
|
+
},
|
|
17435
|
+
methodSignature: {
|
|
17436
|
+
rule: "repeated",
|
|
17437
|
+
type: "string",
|
|
17438
|
+
id: 1051,
|
|
17439
|
+
extend: "google.protobuf.MethodOptions"
|
|
17440
|
+
},
|
|
17441
|
+
defaultHost: {
|
|
17442
|
+
type: "string",
|
|
17443
|
+
id: 1049,
|
|
17444
|
+
extend: "google.protobuf.ServiceOptions"
|
|
17445
|
+
},
|
|
17446
|
+
oauthScopes: {
|
|
17447
|
+
type: "string",
|
|
17448
|
+
id: 1050,
|
|
17449
|
+
extend: "google.protobuf.ServiceOptions"
|
|
17450
|
+
},
|
|
17451
|
+
fieldBehavior: {
|
|
17452
|
+
rule: "repeated",
|
|
17453
|
+
type: "google.api.FieldBehavior",
|
|
17454
|
+
id: 1052,
|
|
17455
|
+
extend: "google.protobuf.FieldOptions"
|
|
17456
|
+
},
|
|
17457
|
+
FieldBehavior: {
|
|
17458
|
+
values: {
|
|
17459
|
+
FIELD_BEHAVIOR_UNSPECIFIED: 0,
|
|
17460
|
+
OPTIONAL: 1,
|
|
17461
|
+
REQUIRED: 2,
|
|
17462
|
+
OUTPUT_ONLY: 3,
|
|
17463
|
+
INPUT_ONLY: 4,
|
|
17464
|
+
IMMUTABLE: 5,
|
|
17465
|
+
UNORDERED_LIST: 6,
|
|
17466
|
+
NON_EMPTY_DEFAULT: 7
|
|
17467
|
+
}
|
|
17075
17468
|
}
|
|
17076
17469
|
}
|
|
17077
17470
|
},
|
|
@@ -20315,6 +20708,9 @@ async function syncEngineRejectListen(syncEngine, targetId, err) {
|
|
|
20315
20708
|
// store to purge a document. However, it would be tricky to keep all of
|
|
20316
20709
|
// the local store's invariants with another method.
|
|
20317
20710
|
let documentUpdates = new SortedMap(DocumentKey.comparator);
|
|
20711
|
+
// TODO(b/217189216): This limbo document should ideally have a read time,
|
|
20712
|
+
// so that it is picked up by any read-time based scans. The backend,
|
|
20713
|
+
// however, does not send a read time for target removals.
|
|
20318
20714
|
documentUpdates = documentUpdates.insert(limboKey, MutableDocument.newNoDocument(limboKey, SnapshotVersion.min()));
|
|
20319
20715
|
const resolvedLimboDocuments = documentKeySet().add(limboKey);
|
|
20320
20716
|
const event = new RemoteEvent(SnapshotVersion.min(),
|
|
@@ -21882,13 +22278,16 @@ class FirestoreClient {
|
|
|
21882
22278
|
this.user = User.UNAUTHENTICATED;
|
|
21883
22279
|
this.clientId = AutoId.newId();
|
|
21884
22280
|
this.authCredentialListener = () => Promise.resolve();
|
|
22281
|
+
this.appCheckCredentialListener = () => Promise.resolve();
|
|
21885
22282
|
this.authCredentials.start(asyncQueue, async (user) => {
|
|
21886
22283
|
logDebug(LOG_TAG$2, 'Received user=', user.uid);
|
|
21887
22284
|
await this.authCredentialListener(user);
|
|
21888
22285
|
this.user = user;
|
|
21889
22286
|
});
|
|
21890
|
-
|
|
21891
|
-
|
|
22287
|
+
this.appCheckCredentials.start(asyncQueue, newAppCheckToken => {
|
|
22288
|
+
logDebug(LOG_TAG$2, 'Received new app check token=', newAppCheckToken);
|
|
22289
|
+
return this.appCheckCredentialListener(newAppCheckToken, this.user);
|
|
22290
|
+
});
|
|
21892
22291
|
}
|
|
21893
22292
|
async getConfiguration() {
|
|
21894
22293
|
return {
|
|
@@ -21904,6 +22303,9 @@ class FirestoreClient {
|
|
|
21904
22303
|
setCredentialChangeListener(listener) {
|
|
21905
22304
|
this.authCredentialListener = listener;
|
|
21906
22305
|
}
|
|
22306
|
+
setAppCheckTokenChangeListener(listener) {
|
|
22307
|
+
this.appCheckCredentialListener = listener;
|
|
22308
|
+
}
|
|
21907
22309
|
/**
|
|
21908
22310
|
* Checks that the client has not been terminated. Ensures that other methods on
|
|
21909
22311
|
* this class cannot be called after the client is terminated.
|
|
@@ -21965,6 +22367,7 @@ async function setOnlineComponentProvider(client, onlineComponentProvider) {
|
|
|
21965
22367
|
// The CredentialChangeListener of the online component provider takes
|
|
21966
22368
|
// precedence over the offline component provider.
|
|
21967
22369
|
client.setCredentialChangeListener(user => remoteStoreHandleCredentialChange(onlineComponentProvider.remoteStore, user));
|
|
22370
|
+
client.setAppCheckTokenChangeListener((_, user) => remoteStoreHandleCredentialChange(onlineComponentProvider.remoteStore, user));
|
|
21968
22371
|
client.onlineComponents = onlineComponentProvider;
|
|
21969
22372
|
}
|
|
21970
22373
|
async function ensureOfflineComponents(client) {
|
|
@@ -22252,72 +22655,6 @@ function createBundleReader(data, serializer) {
|
|
|
22252
22655
|
return newBundleReader(toByteStreamReader(content), serializer);
|
|
22253
22656
|
}
|
|
22254
22657
|
|
|
22255
|
-
/**
|
|
22256
|
-
* @license
|
|
22257
|
-
* Copyright 2017 Google LLC
|
|
22258
|
-
*
|
|
22259
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
22260
|
-
* you may not use this file except in compliance with the License.
|
|
22261
|
-
* You may obtain a copy of the License at
|
|
22262
|
-
*
|
|
22263
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
22264
|
-
*
|
|
22265
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
22266
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
22267
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
22268
|
-
* See the License for the specific language governing permissions and
|
|
22269
|
-
* limitations under the License.
|
|
22270
|
-
*/
|
|
22271
|
-
class DatabaseInfo {
|
|
22272
|
-
/**
|
|
22273
|
-
* Constructs a DatabaseInfo using the provided host, databaseId and
|
|
22274
|
-
* persistenceKey.
|
|
22275
|
-
*
|
|
22276
|
-
* @param databaseId - The database to use.
|
|
22277
|
-
* @param appId - The Firebase App Id.
|
|
22278
|
-
* @param persistenceKey - A unique identifier for this Firestore's local
|
|
22279
|
-
* storage (used in conjunction with the databaseId).
|
|
22280
|
-
* @param host - The Firestore backend host to connect to.
|
|
22281
|
-
* @param ssl - Whether to use SSL when connecting.
|
|
22282
|
-
* @param forceLongPolling - Whether to use the forceLongPolling option
|
|
22283
|
-
* when using WebChannel as the network transport.
|
|
22284
|
-
* @param autoDetectLongPolling - Whether to use the detectBufferingProxy
|
|
22285
|
-
* option when using WebChannel as the network transport.
|
|
22286
|
-
* @param useFetchStreams Whether to use the Fetch API instead of
|
|
22287
|
-
* XMLHTTPRequest
|
|
22288
|
-
*/
|
|
22289
|
-
constructor(databaseId, appId, persistenceKey, host, ssl, forceLongPolling, autoDetectLongPolling, useFetchStreams) {
|
|
22290
|
-
this.databaseId = databaseId;
|
|
22291
|
-
this.appId = appId;
|
|
22292
|
-
this.persistenceKey = persistenceKey;
|
|
22293
|
-
this.host = host;
|
|
22294
|
-
this.ssl = ssl;
|
|
22295
|
-
this.forceLongPolling = forceLongPolling;
|
|
22296
|
-
this.autoDetectLongPolling = autoDetectLongPolling;
|
|
22297
|
-
this.useFetchStreams = useFetchStreams;
|
|
22298
|
-
}
|
|
22299
|
-
}
|
|
22300
|
-
/** The default database name for a project. */
|
|
22301
|
-
const DEFAULT_DATABASE_NAME = '(default)';
|
|
22302
|
-
/**
|
|
22303
|
-
* Represents the database ID a Firestore client is associated with.
|
|
22304
|
-
* @internal
|
|
22305
|
-
*/
|
|
22306
|
-
class DatabaseId {
|
|
22307
|
-
constructor(projectId, database) {
|
|
22308
|
-
this.projectId = projectId;
|
|
22309
|
-
this.database = database ? database : DEFAULT_DATABASE_NAME;
|
|
22310
|
-
}
|
|
22311
|
-
get isDefaultDatabase() {
|
|
22312
|
-
return this.database === DEFAULT_DATABASE_NAME;
|
|
22313
|
-
}
|
|
22314
|
-
isEqual(other) {
|
|
22315
|
-
return (other instanceof DatabaseId &&
|
|
22316
|
-
other.projectId === this.projectId &&
|
|
22317
|
-
other.database === this.database);
|
|
22318
|
-
}
|
|
22319
|
-
}
|
|
22320
|
-
|
|
22321
22658
|
/**
|
|
22322
22659
|
* @license
|
|
22323
22660
|
* Copyright 2020 Google LLC
|
|
@@ -23517,13 +23854,13 @@ function terminate(firestore) {
|
|
|
23517
23854
|
/**
|
|
23518
23855
|
* Loads a Firestore bundle into the local cache.
|
|
23519
23856
|
*
|
|
23520
|
-
* @param firestore - The {@link Firestore} instance to load bundles for
|
|
23521
|
-
* @param bundleData - An object representing the bundle to be loaded. Valid
|
|
23522
|
-
*
|
|
23857
|
+
* @param firestore - The {@link Firestore} instance to load bundles for.
|
|
23858
|
+
* @param bundleData - An object representing the bundle to be loaded. Valid
|
|
23859
|
+
* objects are `ArrayBuffer`, `ReadableStream<Uint8Array>` or `string`.
|
|
23523
23860
|
*
|
|
23524
|
-
* @returns
|
|
23525
|
-
*
|
|
23526
|
-
*
|
|
23861
|
+
* @returns A `LoadBundleTask` object, which notifies callers with progress
|
|
23862
|
+
* updates, and completion or error events. It can be used as a
|
|
23863
|
+
* `Promise<LoadBundleTaskProgress>`.
|
|
23527
23864
|
*/
|
|
23528
23865
|
function loadBundle(firestore, bundleData) {
|
|
23529
23866
|
firestore = cast(firestore, Firestore);
|
|
@@ -23533,11 +23870,16 @@ function loadBundle(firestore, bundleData) {
|
|
|
23533
23870
|
return resultTask;
|
|
23534
23871
|
}
|
|
23535
23872
|
/**
|
|
23536
|
-
* Reads a Firestore {@link Query} from local cache, identified by the given
|
|
23873
|
+
* Reads a Firestore {@link Query} from local cache, identified by the given
|
|
23874
|
+
* name.
|
|
23537
23875
|
*
|
|
23538
23876
|
* The named queries are packaged into bundles on the server side (along
|
|
23539
|
-
* with resulting documents), and loaded to local cache using `loadBundle`. Once
|
|
23540
|
-
* cache, use this method to extract a {@link Query} by name.
|
|
23877
|
+
* with resulting documents), and loaded to local cache using `loadBundle`. Once
|
|
23878
|
+
* in local cache, use this method to extract a {@link Query} by name.
|
|
23879
|
+
*
|
|
23880
|
+
* @param firestore - The {@link Firestore} instance to read the query from.
|
|
23881
|
+
* @param name - The name of the query.
|
|
23882
|
+
* @returns A `Promise` that is resolved with the Query or `null`.
|
|
23541
23883
|
*/
|
|
23542
23884
|
function namedQuery(firestore, name) {
|
|
23543
23885
|
firestore = cast(firestore, Firestore);
|
|
@@ -24686,8 +25028,7 @@ class DocumentSnapshot extends DocumentSnapshot$1 {
|
|
|
24686
25028
|
this.metadata = metadata;
|
|
24687
25029
|
}
|
|
24688
25030
|
/**
|
|
24689
|
-
*
|
|
24690
|
-
* exists. True if the document exists.
|
|
25031
|
+
* Returns whether or not the data exists. True if the document exists.
|
|
24691
25032
|
*/
|
|
24692
25033
|
exists() {
|
|
24693
25034
|
return super.exists();
|
|
@@ -25061,51 +25402,53 @@ function limitToLast(limit) {
|
|
|
25061
25402
|
return new QueryLimitConstraint('limitToLast', limit, "L" /* Last */);
|
|
25062
25403
|
}
|
|
25063
25404
|
class QueryStartAtConstraint extends QueryConstraint {
|
|
25064
|
-
constructor(type, _docOrFields,
|
|
25405
|
+
constructor(type, _docOrFields, _inclusive) {
|
|
25065
25406
|
super();
|
|
25066
25407
|
this.type = type;
|
|
25067
25408
|
this._docOrFields = _docOrFields;
|
|
25068
|
-
this.
|
|
25409
|
+
this._inclusive = _inclusive;
|
|
25069
25410
|
}
|
|
25070
25411
|
_apply(query) {
|
|
25071
|
-
const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this.
|
|
25412
|
+
const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._inclusive);
|
|
25072
25413
|
return new Query(query.firestore, query.converter, queryWithStartAt(query._query, bound));
|
|
25073
25414
|
}
|
|
25074
25415
|
}
|
|
25075
25416
|
function startAt(...docOrFields) {
|
|
25076
|
-
return new QueryStartAtConstraint('startAt', docOrFields,
|
|
25417
|
+
return new QueryStartAtConstraint('startAt', docOrFields,
|
|
25418
|
+
/*inclusive=*/ true);
|
|
25077
25419
|
}
|
|
25078
25420
|
function startAfter(...docOrFields) {
|
|
25079
25421
|
return new QueryStartAtConstraint('startAfter', docOrFields,
|
|
25080
|
-
/*
|
|
25422
|
+
/*inclusive=*/ false);
|
|
25081
25423
|
}
|
|
25082
25424
|
class QueryEndAtConstraint extends QueryConstraint {
|
|
25083
|
-
constructor(type, _docOrFields,
|
|
25425
|
+
constructor(type, _docOrFields, _inclusive) {
|
|
25084
25426
|
super();
|
|
25085
25427
|
this.type = type;
|
|
25086
25428
|
this._docOrFields = _docOrFields;
|
|
25087
|
-
this.
|
|
25429
|
+
this._inclusive = _inclusive;
|
|
25088
25430
|
}
|
|
25089
25431
|
_apply(query) {
|
|
25090
|
-
const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this.
|
|
25432
|
+
const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._inclusive);
|
|
25091
25433
|
return new Query(query.firestore, query.converter, queryWithEndAt(query._query, bound));
|
|
25092
25434
|
}
|
|
25093
25435
|
}
|
|
25094
25436
|
function endBefore(...docOrFields) {
|
|
25095
|
-
return new QueryEndAtConstraint('endBefore', docOrFields,
|
|
25437
|
+
return new QueryEndAtConstraint('endBefore', docOrFields,
|
|
25438
|
+
/*inclusive=*/ false);
|
|
25096
25439
|
}
|
|
25097
25440
|
function endAt(...docOrFields) {
|
|
25098
|
-
return new QueryEndAtConstraint('endAt', docOrFields, /*
|
|
25441
|
+
return new QueryEndAtConstraint('endAt', docOrFields, /*inclusive=*/ true);
|
|
25099
25442
|
}
|
|
25100
25443
|
/** Helper function to create a bound from a document or fields */
|
|
25101
|
-
function newQueryBoundFromDocOrFields(query, methodName, docOrFields,
|
|
25444
|
+
function newQueryBoundFromDocOrFields(query, methodName, docOrFields, inclusive) {
|
|
25102
25445
|
docOrFields[0] = util$1.getModularInstance(docOrFields[0]);
|
|
25103
25446
|
if (docOrFields[0] instanceof DocumentSnapshot$1) {
|
|
25104
|
-
return newQueryBoundFromDocument(query._query, query.firestore._databaseId, methodName, docOrFields[0]._document,
|
|
25447
|
+
return newQueryBoundFromDocument(query._query, query.firestore._databaseId, methodName, docOrFields[0]._document, inclusive);
|
|
25105
25448
|
}
|
|
25106
25449
|
else {
|
|
25107
25450
|
const reader = newUserDataReader(query.firestore);
|
|
25108
|
-
return newQueryBoundFromFields(query._query, query.firestore._databaseId, reader, methodName, docOrFields,
|
|
25451
|
+
return newQueryBoundFromFields(query._query, query.firestore._databaseId, reader, methodName, docOrFields, inclusive);
|
|
25109
25452
|
}
|
|
25110
25453
|
}
|
|
25111
25454
|
function newQueryFilter(query, methodName, dataReader, databaseId, fieldPath, op, value) {
|
|
@@ -25163,7 +25506,7 @@ function newQueryOrderBy(query, fieldPath, direction) {
|
|
|
25163
25506
|
* of the query or if any of the fields in the order by are an uncommitted
|
|
25164
25507
|
* server timestamp.
|
|
25165
25508
|
*/
|
|
25166
|
-
function newQueryBoundFromDocument(query, databaseId, methodName, doc,
|
|
25509
|
+
function newQueryBoundFromDocument(query, databaseId, methodName, doc, inclusive) {
|
|
25167
25510
|
if (!doc) {
|
|
25168
25511
|
throw new FirestoreError(Code.NOT_FOUND, `Can't use a DocumentSnapshot that doesn't exist for ` +
|
|
25169
25512
|
`${methodName}().`);
|
|
@@ -25200,12 +25543,12 @@ function newQueryBoundFromDocument(query, databaseId, methodName, doc, before) {
|
|
|
25200
25543
|
}
|
|
25201
25544
|
}
|
|
25202
25545
|
}
|
|
25203
|
-
return new Bound(components,
|
|
25546
|
+
return new Bound(components, inclusive);
|
|
25204
25547
|
}
|
|
25205
25548
|
/**
|
|
25206
25549
|
* Converts a list of field values to a `Bound` for the given query.
|
|
25207
25550
|
*/
|
|
25208
|
-
function newQueryBoundFromFields(query, databaseId, dataReader, methodName, values,
|
|
25551
|
+
function newQueryBoundFromFields(query, databaseId, dataReader, methodName, values, inclusive) {
|
|
25209
25552
|
// Use explicit order by's because it has to match the query the user made
|
|
25210
25553
|
const orderBy = query.explicitOrderBy;
|
|
25211
25554
|
if (values.length > orderBy.length) {
|
|
@@ -25242,7 +25585,7 @@ function newQueryBoundFromFields(query, databaseId, dataReader, methodName, valu
|
|
|
25242
25585
|
components.push(wrapped);
|
|
25243
25586
|
}
|
|
25244
25587
|
}
|
|
25245
|
-
return new Bound(components,
|
|
25588
|
+
return new Bound(components, inclusive);
|
|
25246
25589
|
}
|
|
25247
25590
|
/**
|
|
25248
25591
|
* Parses the given `documentIdValue` into a `ReferenceValue`, throwing
|
|
@@ -26227,6 +26570,71 @@ function writeBatch(firestore) {
|
|
|
26227
26570
|
return new WriteBatch(firestore, mutations => executeWrite(firestore, mutations));
|
|
26228
26571
|
}
|
|
26229
26572
|
|
|
26573
|
+
/**
|
|
26574
|
+
* @license
|
|
26575
|
+
* Copyright 2021 Google LLC
|
|
26576
|
+
*
|
|
26577
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
26578
|
+
* you may not use this file except in compliance with the License.
|
|
26579
|
+
* You may obtain a copy of the License at
|
|
26580
|
+
*
|
|
26581
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
26582
|
+
*
|
|
26583
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
26584
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
26585
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
26586
|
+
* See the License for the specific language governing permissions and
|
|
26587
|
+
* limitations under the License.
|
|
26588
|
+
*/
|
|
26589
|
+
function setIndexConfiguration(firestore, jsonOrConfiguration) {
|
|
26590
|
+
firestore = cast(firestore, Firestore);
|
|
26591
|
+
ensureFirestoreConfigured(firestore);
|
|
26592
|
+
const indexConfiguration = typeof jsonOrConfiguration === 'string'
|
|
26593
|
+
? tryParseJson(jsonOrConfiguration)
|
|
26594
|
+
: jsonOrConfiguration;
|
|
26595
|
+
const parsedIndexes = [];
|
|
26596
|
+
// PORTING NOTE: We don't return an error if the user has not enabled
|
|
26597
|
+
// persistence since `enableIndexeddbPersistence()` can fail on the Web.
|
|
26598
|
+
if (Array.isArray(indexConfiguration.indexes)) {
|
|
26599
|
+
for (const index of indexConfiguration.indexes) {
|
|
26600
|
+
const collectionGroup = tryGetString(index, 'collectionGroup');
|
|
26601
|
+
const segments = [];
|
|
26602
|
+
if (Array.isArray(index.fields)) {
|
|
26603
|
+
for (const field of index.fields) {
|
|
26604
|
+
const fieldPathString = tryGetString(field, 'fieldPath');
|
|
26605
|
+
const fieldPath = fieldPathFromDotSeparatedString('setIndexConfiguration', fieldPathString);
|
|
26606
|
+
if (field.arrayConfig === 'CONTAINS') {
|
|
26607
|
+
segments.push(new IndexSegment(fieldPath, 2 /* CONTAINS */));
|
|
26608
|
+
}
|
|
26609
|
+
else if (field.order === 'ASCENDING') {
|
|
26610
|
+
segments.push(new IndexSegment(fieldPath, 0 /* ASCENDING */));
|
|
26611
|
+
}
|
|
26612
|
+
else if (field.order === 'DESCENDING') {
|
|
26613
|
+
segments.push(new IndexSegment(fieldPath, 1 /* DESCENDING */));
|
|
26614
|
+
}
|
|
26615
|
+
}
|
|
26616
|
+
}
|
|
26617
|
+
parsedIndexes.push(new FieldIndex(FieldIndex.UNKNOWN_ID, collectionGroup, segments, IndexState.empty()));
|
|
26618
|
+
}
|
|
26619
|
+
}
|
|
26620
|
+
// TODO(indexing): Configure indexes
|
|
26621
|
+
return Promise.resolve();
|
|
26622
|
+
}
|
|
26623
|
+
function tryParseJson(json) {
|
|
26624
|
+
try {
|
|
26625
|
+
return JSON.parse(json);
|
|
26626
|
+
}
|
|
26627
|
+
catch (e) {
|
|
26628
|
+
throw new FirestoreError(Code.INVALID_ARGUMENT, 'Failed to parse JSON:' + e.message);
|
|
26629
|
+
}
|
|
26630
|
+
}
|
|
26631
|
+
function tryGetString(data, property) {
|
|
26632
|
+
if (typeof data[property] !== 'string') {
|
|
26633
|
+
throw new FirestoreError(Code.INVALID_ARGUMENT, 'Missing string value for: ' + property);
|
|
26634
|
+
}
|
|
26635
|
+
return data[property];
|
|
26636
|
+
}
|
|
26637
|
+
|
|
26230
26638
|
/**
|
|
26231
26639
|
* @license
|
|
26232
26640
|
* Copyright 2021 Google LLC
|
|
@@ -26274,6 +26682,7 @@ exports._cast = cast;
|
|
|
26274
26682
|
exports._debugAssert = debugAssert;
|
|
26275
26683
|
exports._isBase64Available = isBase64Available;
|
|
26276
26684
|
exports._logWarn = logWarn;
|
|
26685
|
+
exports._setIndexConfiguration = setIndexConfiguration;
|
|
26277
26686
|
exports._validateIsNotUsedTogether = validateIsNotUsedTogether;
|
|
26278
26687
|
exports.addDoc = addDoc;
|
|
26279
26688
|
exports.arrayRemove = arrayRemove;
|