@firebase/firestore 3.4.4-canary.2dd99ae2d → 3.4.4-canary.3fe2c4a03
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/dist/firestore/src/api/snapshot.d.ts +1 -2
- package/dist/firestore/src/core/target.d.ts +8 -4
- 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 +21 -2
- package/dist/firestore/src/local/indexeddb_persistence.d.ts +4 -4
- package/dist/firestore/src/local/indexeddb_remote_document_cache.d.ts +2 -8
- package/dist/firestore/src/local/indexeddb_schema.d.ts +149 -7
- package/dist/firestore/src/local/local_documents_view.d.ts +0 -1
- package/dist/firestore/src/local/local_serializer.d.ts +7 -2
- package/dist/firestore/src/local/memory_index_manager.d.ts +11 -0
- package/dist/firestore/src/local/memory_persistence.d.ts +3 -2
- package/dist/firestore/src/local/memory_remote_document_cache.d.ts +1 -3
- package/dist/firestore/src/local/persistence.d.ts +2 -2
- package/dist/firestore/src/local/remote_document_cache.d.ts +7 -9
- package/dist/firestore/src/local/simple_db.d.ts +1 -0
- package/dist/firestore/src/model/field_index.d.ts +2 -2
- package/dist/firestore/test/unit/local/counting_query_engine.d.ts +3 -3
- package/dist/firestore/test/unit/local/persistence_test_helpers.d.ts +1 -0
- package/dist/firestore/test/unit/local/test_index_manager.d.ts +11 -0
- package/dist/firestore/test/unit/local/test_remote_document_cache.d.ts +4 -2
- package/dist/firestore/test/unit/local/test_remote_document_change_buffer.d.ts +1 -1
- package/dist/firestore/test/util/helpers.d.ts +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.esm2017.js +3357 -3133
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm5.js +3588 -3382
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +475 -212
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/index.node.mjs +475 -212
- package/dist/index.node.mjs.map +1 -1
- package/dist/index.rn.js +3535 -3311
- package/dist/index.rn.js.map +1 -1
- package/dist/internal.d.ts +178 -14
- package/dist/lite/firestore/src/api/snapshot.d.ts +1 -2
- package/dist/lite/firestore/src/core/target.d.ts +8 -4
- 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 +21 -2
- package/dist/lite/firestore/src/local/indexeddb_persistence.d.ts +4 -4
- package/dist/lite/firestore/src/local/indexeddb_remote_document_cache.d.ts +2 -8
- package/dist/lite/firestore/src/local/indexeddb_schema.d.ts +149 -7
- package/dist/lite/firestore/src/local/local_documents_view.d.ts +0 -1
- package/dist/lite/firestore/src/local/local_serializer.d.ts +7 -2
- package/dist/lite/firestore/src/local/memory_index_manager.d.ts +11 -0
- package/dist/lite/firestore/src/local/memory_persistence.d.ts +3 -2
- package/dist/lite/firestore/src/local/memory_remote_document_cache.d.ts +1 -3
- package/dist/lite/firestore/src/local/persistence.d.ts +2 -2
- package/dist/lite/firestore/src/local/remote_document_cache.d.ts +7 -9
- package/dist/lite/firestore/src/local/simple_db.d.ts +1 -0
- package/dist/lite/firestore/src/model/field_index.d.ts +2 -2
- package/dist/lite/firestore/test/unit/local/counting_query_engine.d.ts +3 -3
- package/dist/lite/firestore/test/unit/local/persistence_test_helpers.d.ts +1 -0
- package/dist/lite/firestore/test/unit/local/test_index_manager.d.ts +11 -0
- package/dist/lite/firestore/test/unit/local/test_remote_document_cache.d.ts +4 -2
- package/dist/lite/firestore/test/unit/local/test_remote_document_change_buffer.d.ts +1 -1
- package/dist/lite/firestore/test/util/helpers.d.ts +1 -1
- package/dist/lite/index.browser.esm2017.js +1146 -1143
- package/dist/lite/index.browser.esm2017.js.map +1 -1
- package/dist/lite/index.browser.esm5.js +332 -331
- package/dist/lite/index.browser.esm5.js.map +1 -1
- package/dist/lite/index.node.cjs.js +36 -29
- package/dist/lite/index.node.cjs.js.map +1 -1
- package/dist/lite/index.node.mjs +36 -29
- package/dist/lite/index.node.mjs.map +1 -1
- package/dist/lite/index.rn.esm2017.js +301 -298
- package/dist/lite/index.rn.esm2017.js.map +1 -1
- package/dist/lite/internal.d.ts +2 -2
- package/dist/lite/packages/firestore/dist/lite/index.browser.esm2017.d.ts +121 -121
- package/dist/lite/packages/firestore/src/api/snapshot.d.ts +1 -2
- package/dist/lite/packages/firestore/src/core/target.d.ts +8 -4
- 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 +21 -2
- package/dist/lite/packages/firestore/src/local/indexeddb_persistence.d.ts +4 -4
- package/dist/lite/packages/firestore/src/local/indexeddb_remote_document_cache.d.ts +2 -8
- package/dist/lite/packages/firestore/src/local/indexeddb_schema.d.ts +149 -7
- package/dist/lite/packages/firestore/src/local/local_documents_view.d.ts +0 -1
- package/dist/lite/packages/firestore/src/local/local_serializer.d.ts +7 -2
- package/dist/lite/packages/firestore/src/local/memory_index_manager.d.ts +11 -0
- package/dist/lite/packages/firestore/src/local/memory_persistence.d.ts +3 -2
- package/dist/lite/packages/firestore/src/local/memory_remote_document_cache.d.ts +1 -3
- package/dist/lite/packages/firestore/src/local/persistence.d.ts +2 -2
- package/dist/lite/packages/firestore/src/local/remote_document_cache.d.ts +7 -9
- package/dist/lite/packages/firestore/src/local/simple_db.d.ts +1 -0
- package/dist/lite/packages/firestore/src/model/field_index.d.ts +2 -2
- package/dist/lite/packages/firestore/test/unit/local/counting_query_engine.d.ts +3 -3
- package/dist/lite/packages/firestore/test/unit/local/persistence_test_helpers.d.ts +1 -0
- package/dist/lite/packages/firestore/test/unit/local/test_index_manager.d.ts +11 -0
- package/dist/lite/packages/firestore/test/unit/local/test_remote_document_cache.d.ts +4 -2
- package/dist/lite/packages/firestore/test/unit/local/test_remote_document_change_buffer.d.ts +1 -1
- package/dist/lite/packages/firestore/test/util/helpers.d.ts +1 -1
- package/dist/lite/private.d.ts +2 -2
- package/dist/packages/firestore/dist/index.esm2017.d.ts +177 -177
- package/dist/packages/firestore/src/api/snapshot.d.ts +1 -2
- package/dist/packages/firestore/src/core/target.d.ts +8 -4
- 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 +21 -2
- package/dist/packages/firestore/src/local/indexeddb_persistence.d.ts +4 -4
- package/dist/packages/firestore/src/local/indexeddb_remote_document_cache.d.ts +2 -8
- package/dist/packages/firestore/src/local/indexeddb_schema.d.ts +149 -7
- package/dist/packages/firestore/src/local/local_documents_view.d.ts +0 -1
- package/dist/packages/firestore/src/local/local_serializer.d.ts +7 -2
- package/dist/packages/firestore/src/local/memory_index_manager.d.ts +11 -0
- package/dist/packages/firestore/src/local/memory_persistence.d.ts +3 -2
- package/dist/packages/firestore/src/local/memory_remote_document_cache.d.ts +1 -3
- package/dist/packages/firestore/src/local/persistence.d.ts +2 -2
- package/dist/packages/firestore/src/local/remote_document_cache.d.ts +7 -9
- package/dist/packages/firestore/src/local/simple_db.d.ts +1 -0
- package/dist/packages/firestore/src/model/field_index.d.ts +2 -2
- package/dist/packages/firestore/test/unit/local/counting_query_engine.d.ts +3 -3
- package/dist/packages/firestore/test/unit/local/persistence_test_helpers.d.ts +1 -0
- package/dist/packages/firestore/test/unit/local/test_index_manager.d.ts +11 -0
- package/dist/packages/firestore/test/unit/local/test_remote_document_cache.d.ts +4 -2
- package/dist/packages/firestore/test/unit/local/test_remote_document_change_buffer.d.ts +1 -1
- package/dist/packages/firestore/test/util/helpers.d.ts +1 -1
- package/dist/private.d.ts +178 -14
- package/package.json +9 -9
package/dist/index.node.mjs
CHANGED
|
@@ -8,7 +8,7 @@ import { credentials, loadPackageDefinition, Metadata } from '@grpc/grpc-js';
|
|
|
8
8
|
import { fromJSON } from '@grpc/proto-loader';
|
|
9
9
|
|
|
10
10
|
const name = "@firebase/firestore";
|
|
11
|
-
const version$1 = "3.4.4-canary.
|
|
11
|
+
const version$1 = "3.4.4-canary.3fe2c4a03";
|
|
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.
|
|
64
|
+
const version = "9.6.6-canary.3fe2c4a03";
|
|
65
65
|
|
|
66
66
|
/**
|
|
67
67
|
* @license
|
|
@@ -1192,23 +1192,6 @@ function decodeResourcePath(path) {
|
|
|
1192
1192
|
}
|
|
1193
1193
|
return new ResourcePath(segments);
|
|
1194
1194
|
}
|
|
1195
|
-
|
|
1196
|
-
/**
|
|
1197
|
-
* @license
|
|
1198
|
-
* Copyright 2017 Google LLC
|
|
1199
|
-
*
|
|
1200
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1201
|
-
* you may not use this file except in compliance with the License.
|
|
1202
|
-
* You may obtain a copy of the License at
|
|
1203
|
-
*
|
|
1204
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1205
|
-
*
|
|
1206
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
1207
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1208
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1209
|
-
* See the License for the specific language governing permissions and
|
|
1210
|
-
* limitations under the License.
|
|
1211
|
-
*/
|
|
1212
1195
|
/**
|
|
1213
1196
|
* Schema Version for the Web client:
|
|
1214
1197
|
* 1. Initial version including Mutation Queue, Query Cache, and Remote
|
|
@@ -1227,6 +1210,7 @@ function decodeResourcePath(path) {
|
|
|
1227
1210
|
* an auto-incrementing ID. This is required for Index-Free queries.
|
|
1228
1211
|
* 10. Rewrite the canonical IDs to the explicit Protobuf-based format.
|
|
1229
1212
|
* 11. Add bundles and named_queries for bundle support.
|
|
1213
|
+
* 12. Add indexing support.
|
|
1230
1214
|
*/
|
|
1231
1215
|
const SCHEMA_VERSION = 11;
|
|
1232
1216
|
/**
|
|
@@ -1753,9 +1737,7 @@ class DbClientMetadata {
|
|
|
1753
1737
|
DbClientMetadata.store = 'clientMetadata';
|
|
1754
1738
|
/** Keys are automatically assigned via the clientId properties. */
|
|
1755
1739
|
DbClientMetadata.keyPath = 'clientId';
|
|
1756
|
-
/**
|
|
1757
|
-
* A object representing a bundle loaded by the SDK.
|
|
1758
|
-
*/
|
|
1740
|
+
/** An object representing a bundle loaded by the SDK. */
|
|
1759
1741
|
class DbBundle {
|
|
1760
1742
|
constructor(
|
|
1761
1743
|
/** The ID of the loaded bundle. */
|
|
@@ -1772,9 +1754,7 @@ class DbBundle {
|
|
|
1772
1754
|
/** Name of the IndexedDb object store. */
|
|
1773
1755
|
DbBundle.store = 'bundles';
|
|
1774
1756
|
DbBundle.keyPath = 'bundleId';
|
|
1775
|
-
/**
|
|
1776
|
-
* A object representing a named query loaded by the SDK via a bundle.
|
|
1777
|
-
*/
|
|
1757
|
+
/** An object representing a named query loaded by the SDK via a bundle. */
|
|
1778
1758
|
class DbNamedQuery {
|
|
1779
1759
|
constructor(
|
|
1780
1760
|
/** The name of the query. */
|
|
@@ -1791,6 +1771,116 @@ class DbNamedQuery {
|
|
|
1791
1771
|
/** Name of the IndexedDb object store. */
|
|
1792
1772
|
DbNamedQuery.store = 'namedQueries';
|
|
1793
1773
|
DbNamedQuery.keyPath = 'name';
|
|
1774
|
+
/** An object representing the global configuration for a field index. */
|
|
1775
|
+
class DbIndexConfiguration {
|
|
1776
|
+
constructor(
|
|
1777
|
+
/**
|
|
1778
|
+
* The index id for this entry. Undefined for indexes that are not yet
|
|
1779
|
+
* persisted.
|
|
1780
|
+
*/
|
|
1781
|
+
indexId,
|
|
1782
|
+
/** The collection group this index belongs to. */
|
|
1783
|
+
collectionGroup,
|
|
1784
|
+
/** The fields to index for this index. */
|
|
1785
|
+
fields) {
|
|
1786
|
+
this.indexId = indexId;
|
|
1787
|
+
this.collectionGroup = collectionGroup;
|
|
1788
|
+
this.fields = fields;
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
/** Name of the IndexedDb object store. */
|
|
1792
|
+
DbIndexConfiguration.store = 'indexConfiguration';
|
|
1793
|
+
DbIndexConfiguration.keyPath = 'indexId';
|
|
1794
|
+
/**
|
|
1795
|
+
* An index that provides access to the index configurations by collection
|
|
1796
|
+
* group.
|
|
1797
|
+
*
|
|
1798
|
+
* PORTING NOTE: iOS and Android maintain this index in-memory, but this is
|
|
1799
|
+
* not possible here as the Web client supports concurrent access to
|
|
1800
|
+
* persistence via multi-tab.
|
|
1801
|
+
*/
|
|
1802
|
+
DbIndexConfiguration.collectionGroupIndex = 'collectionGroupIndex';
|
|
1803
|
+
DbIndexConfiguration.collectionGroupIndexPath = 'collectionGroup';
|
|
1804
|
+
/**
|
|
1805
|
+
* An object describing how up-to-date the index backfill is for each user and
|
|
1806
|
+
* index.
|
|
1807
|
+
*/
|
|
1808
|
+
class DbIndexState {
|
|
1809
|
+
constructor(
|
|
1810
|
+
/** The index id for this entry. */
|
|
1811
|
+
indexId,
|
|
1812
|
+
/** The user id for this entry. */
|
|
1813
|
+
uid,
|
|
1814
|
+
/**
|
|
1815
|
+
* A number that indicates when the index was last updated (relative to
|
|
1816
|
+
* other indexes).
|
|
1817
|
+
*/
|
|
1818
|
+
sequenceNumber,
|
|
1819
|
+
/**
|
|
1820
|
+
* The latest read time that has been indexed by Firestore for this field
|
|
1821
|
+
* index. Set to `{seconds: 0, nanos: 0}` if no documents have been indexed.
|
|
1822
|
+
*/
|
|
1823
|
+
readTime,
|
|
1824
|
+
/**
|
|
1825
|
+
* The last document that has been indexed for this field index. Empty if
|
|
1826
|
+
* no documents have been indexed.
|
|
1827
|
+
*/
|
|
1828
|
+
documentKey,
|
|
1829
|
+
/**
|
|
1830
|
+
* The largest mutation batch id that has been processed for this index. -1
|
|
1831
|
+
* if no mutations have been indexed.
|
|
1832
|
+
*/
|
|
1833
|
+
largestBatchId) {
|
|
1834
|
+
this.indexId = indexId;
|
|
1835
|
+
this.uid = uid;
|
|
1836
|
+
this.sequenceNumber = sequenceNumber;
|
|
1837
|
+
this.readTime = readTime;
|
|
1838
|
+
this.documentKey = documentKey;
|
|
1839
|
+
this.largestBatchId = largestBatchId;
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1842
|
+
/** Name of the IndexedDb object store. */
|
|
1843
|
+
DbIndexState.store = 'indexState';
|
|
1844
|
+
DbIndexState.keyPath = ['indexId', 'uid'];
|
|
1845
|
+
/**
|
|
1846
|
+
* An index that provides access to documents in a collection sorted by last
|
|
1847
|
+
* update time. Used by the backfiller.
|
|
1848
|
+
*
|
|
1849
|
+
* PORTING NOTE: iOS and Android maintain this index in-memory, but this is
|
|
1850
|
+
* not possible here as the Web client supports concurrent access to
|
|
1851
|
+
* persistence via multi-tab.
|
|
1852
|
+
*/
|
|
1853
|
+
DbIndexState.sequenceNumberIndex = 'sequenceNumberIndex';
|
|
1854
|
+
DbIndexState.sequenceNumberIndexPath = ['uid', 'sequenceNumber'];
|
|
1855
|
+
/** An object that stores the encoded entries for all documents and fields. */
|
|
1856
|
+
class DbIndexEntry {
|
|
1857
|
+
constructor(
|
|
1858
|
+
/** The index id for this entry. */
|
|
1859
|
+
indexId,
|
|
1860
|
+
/** The user id for this entry. */
|
|
1861
|
+
uid,
|
|
1862
|
+
/** The encoded array index value for this entry. */
|
|
1863
|
+
arrayValue,
|
|
1864
|
+
/** The encoded directional value for equality and inequality filters. */
|
|
1865
|
+
directionalValue,
|
|
1866
|
+
/** The document key this entry points to. */
|
|
1867
|
+
documentKey) {
|
|
1868
|
+
this.indexId = indexId;
|
|
1869
|
+
this.uid = uid;
|
|
1870
|
+
this.arrayValue = arrayValue;
|
|
1871
|
+
this.directionalValue = directionalValue;
|
|
1872
|
+
this.documentKey = documentKey;
|
|
1873
|
+
}
|
|
1874
|
+
}
|
|
1875
|
+
/** Name of the IndexedDb object store. */
|
|
1876
|
+
DbIndexEntry.store = 'indexEntries';
|
|
1877
|
+
DbIndexEntry.keyPath = [
|
|
1878
|
+
'indexId',
|
|
1879
|
+
'uid',
|
|
1880
|
+
'arrayValue',
|
|
1881
|
+
'directionalValue',
|
|
1882
|
+
'documentKey'
|
|
1883
|
+
];
|
|
1794
1884
|
// Visible for testing
|
|
1795
1885
|
const V1_STORES = [
|
|
1796
1886
|
DbMutationQueue.store,
|
|
@@ -1805,7 +1895,6 @@ const V1_STORES = [
|
|
|
1805
1895
|
// V2 is no longer usable (see comment at top of file)
|
|
1806
1896
|
// Visible for testing
|
|
1807
1897
|
const V3_STORES = V1_STORES;
|
|
1808
|
-
// Visible for testing
|
|
1809
1898
|
// Note: DbRemoteDocumentChanges is no longer used and dropped with v9.
|
|
1810
1899
|
const V4_STORES = [...V3_STORES, DbClientMetadata.store];
|
|
1811
1900
|
// V5 does not change the set of stores.
|
|
@@ -1815,12 +1904,24 @@ const V8_STORES = [...V6_STORES, DbCollectionParent.store];
|
|
|
1815
1904
|
// V9 does not change the set of stores.
|
|
1816
1905
|
// V10 does not change the set of stores.
|
|
1817
1906
|
const V11_STORES = [...V8_STORES, DbBundle.store, DbNamedQuery.store];
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1907
|
+
const V12_STORES = [
|
|
1908
|
+
...V11_STORES,
|
|
1909
|
+
DbIndexConfiguration.store,
|
|
1910
|
+
DbIndexState.store,
|
|
1911
|
+
DbIndexEntry.store
|
|
1912
|
+
];
|
|
1913
|
+
/** Returns the object stores for the provided schema. */
|
|
1914
|
+
function getObjectStores(schemaVersion) {
|
|
1915
|
+
if (schemaVersion === 12) {
|
|
1916
|
+
return V12_STORES;
|
|
1917
|
+
}
|
|
1918
|
+
else if (schemaVersion === 11) {
|
|
1919
|
+
return V11_STORES;
|
|
1920
|
+
}
|
|
1921
|
+
else {
|
|
1922
|
+
fail();
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1824
1925
|
|
|
1825
1926
|
/**
|
|
1826
1927
|
* @license
|
|
@@ -2117,6 +2218,15 @@ class SimpleDbTransaction {
|
|
|
2117
2218
|
this.transaction.abort();
|
|
2118
2219
|
}
|
|
2119
2220
|
}
|
|
2221
|
+
maybeCommit() {
|
|
2222
|
+
// If the browser supports V3 IndexedDB, we invoke commit() explicitly to
|
|
2223
|
+
// speed up index DB processing if the event loop remains blocks.
|
|
2224
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2225
|
+
const maybeV3IndexedDb = this.transaction;
|
|
2226
|
+
if (!this.aborted && typeof maybeV3IndexedDb.commit === 'function') {
|
|
2227
|
+
maybeV3IndexedDb.commit();
|
|
2228
|
+
}
|
|
2229
|
+
}
|
|
2120
2230
|
/**
|
|
2121
2231
|
* Returns a SimpleDbStore<KeyType, ValueType> for the specified store. All
|
|
2122
2232
|
* operations performed on the SimpleDbStore happen within the context of this
|
|
@@ -2313,6 +2423,10 @@ class SimpleDb {
|
|
|
2313
2423
|
this.db = await this.ensureDb(action);
|
|
2314
2424
|
const transaction = SimpleDbTransaction.open(this.db, action, readonly ? 'readonly' : 'readwrite', objectStores);
|
|
2315
2425
|
const transactionFnResult = transactionFn(transaction)
|
|
2426
|
+
.next(result => {
|
|
2427
|
+
transaction.maybeCommit();
|
|
2428
|
+
return result;
|
|
2429
|
+
})
|
|
2316
2430
|
.catch(error => {
|
|
2317
2431
|
// Abort the transaction if there was an error.
|
|
2318
2432
|
transaction.abort(error);
|
|
@@ -4345,12 +4459,12 @@ class FieldIndex {
|
|
|
4345
4459
|
/** The collection ID this index applies to. */
|
|
4346
4460
|
collectionGroup,
|
|
4347
4461
|
/** The field segments for this index. */
|
|
4348
|
-
|
|
4462
|
+
fields,
|
|
4349
4463
|
/** Shows how up-to-date the index is for the current user. */
|
|
4350
4464
|
indexState) {
|
|
4351
4465
|
this.indexId = indexId;
|
|
4352
4466
|
this.collectionGroup = collectionGroup;
|
|
4353
|
-
this.
|
|
4467
|
+
this.fields = fields;
|
|
4354
4468
|
this.indexState = indexState;
|
|
4355
4469
|
}
|
|
4356
4470
|
}
|
|
@@ -4460,27 +4574,29 @@ function newTarget(path, collectionGroup = null, orderBy = [], filters = [], lim
|
|
|
4460
4574
|
function canonifyTarget(target) {
|
|
4461
4575
|
const targetImpl = debugCast(target);
|
|
4462
4576
|
if (targetImpl.memoizedCanonicalId === null) {
|
|
4463
|
-
let
|
|
4577
|
+
let str = targetImpl.path.canonicalString();
|
|
4464
4578
|
if (targetImpl.collectionGroup !== null) {
|
|
4465
|
-
|
|
4579
|
+
str += '|cg:' + targetImpl.collectionGroup;
|
|
4466
4580
|
}
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
|
|
4581
|
+
str += '|f:';
|
|
4582
|
+
str += targetImpl.filters.map(f => canonifyFilter(f)).join(',');
|
|
4583
|
+
str += '|ob:';
|
|
4584
|
+
str += targetImpl.orderBy.map(o => canonifyOrderBy(o)).join(',');
|
|
4471
4585
|
if (!isNullOrUndefined(targetImpl.limit)) {
|
|
4472
|
-
|
|
4473
|
-
|
|
4586
|
+
str += '|l:';
|
|
4587
|
+
str += targetImpl.limit;
|
|
4474
4588
|
}
|
|
4475
4589
|
if (targetImpl.startAt) {
|
|
4476
|
-
|
|
4477
|
-
|
|
4590
|
+
str += '|lb:';
|
|
4591
|
+
str += targetImpl.startAt.inclusive ? 'b:' : 'a:';
|
|
4592
|
+
str += targetImpl.startAt.position.map(p => canonicalId(p)).join(',');
|
|
4478
4593
|
}
|
|
4479
4594
|
if (targetImpl.endAt) {
|
|
4480
|
-
|
|
4481
|
-
|
|
4595
|
+
str += '|ub:';
|
|
4596
|
+
str += targetImpl.endAt.inclusive ? 'a:' : 'b:';
|
|
4597
|
+
str += targetImpl.endAt.position.map(p => canonicalId(p)).join(',');
|
|
4482
4598
|
}
|
|
4483
|
-
targetImpl.memoizedCanonicalId =
|
|
4599
|
+
targetImpl.memoizedCanonicalId = str;
|
|
4484
4600
|
}
|
|
4485
4601
|
return targetImpl.memoizedCanonicalId;
|
|
4486
4602
|
}
|
|
@@ -4503,10 +4619,14 @@ function stringifyTarget(target) {
|
|
|
4503
4619
|
.join(', ')}]`;
|
|
4504
4620
|
}
|
|
4505
4621
|
if (target.startAt) {
|
|
4506
|
-
str += ', startAt: '
|
|
4622
|
+
str += ', startAt: ';
|
|
4623
|
+
str += target.startAt.inclusive ? 'b:' : 'a:';
|
|
4624
|
+
str += target.startAt.position.map(p => canonicalId(p)).join(',');
|
|
4507
4625
|
}
|
|
4508
4626
|
if (target.endAt) {
|
|
4509
|
-
str += ', endAt: '
|
|
4627
|
+
str += ', endAt: ';
|
|
4628
|
+
str += target.endAt.inclusive ? 'a:' : 'b:';
|
|
4629
|
+
str += target.endAt.position.map(p => canonicalId(p)).join(',');
|
|
4510
4630
|
}
|
|
4511
4631
|
return `Target(${str})`;
|
|
4512
4632
|
}
|
|
@@ -4729,7 +4849,6 @@ class ArrayContainsAnyFilter extends FieldFilter {
|
|
|
4729
4849
|
return other.arrayValue.values.some(val => arrayValueContains(this.value.arrayValue, val));
|
|
4730
4850
|
}
|
|
4731
4851
|
}
|
|
4732
|
-
// TODO(indexing): Change Bound.before to "inclusive"
|
|
4733
4852
|
/**
|
|
4734
4853
|
* Represents a bound of a query.
|
|
4735
4854
|
*
|
|
@@ -4745,17 +4864,11 @@ class ArrayContainsAnyFilter extends FieldFilter {
|
|
|
4745
4864
|
* just after the provided values.
|
|
4746
4865
|
*/
|
|
4747
4866
|
class Bound {
|
|
4748
|
-
constructor(position,
|
|
4867
|
+
constructor(position, inclusive) {
|
|
4749
4868
|
this.position = position;
|
|
4750
|
-
this.
|
|
4869
|
+
this.inclusive = inclusive;
|
|
4751
4870
|
}
|
|
4752
4871
|
}
|
|
4753
|
-
function canonifyBound(bound) {
|
|
4754
|
-
// TODO(b/29183165): Make this collision robust.
|
|
4755
|
-
return `${bound.before ? 'b' : 'a'}:${bound.position
|
|
4756
|
-
.map(p => canonicalId(p))
|
|
4757
|
-
.join(',')}`;
|
|
4758
|
-
}
|
|
4759
4872
|
/**
|
|
4760
4873
|
* An ordering on a field, in some Direction. Direction defaults to ASCENDING.
|
|
4761
4874
|
*/
|
|
@@ -4775,11 +4888,7 @@ function stringifyOrderBy(orderBy) {
|
|
|
4775
4888
|
function orderByEquals(left, right) {
|
|
4776
4889
|
return left.dir === right.dir && left.field.isEqual(right.field);
|
|
4777
4890
|
}
|
|
4778
|
-
|
|
4779
|
-
* Returns true if a document sorts before a bound using the provided sort
|
|
4780
|
-
* order.
|
|
4781
|
-
*/
|
|
4782
|
-
function sortsBeforeDocument(bound, orderBy, doc) {
|
|
4891
|
+
function boundCompareToDocument(bound, orderBy, doc) {
|
|
4783
4892
|
let comparison = 0;
|
|
4784
4893
|
for (let i = 0; i < bound.position.length; i++) {
|
|
4785
4894
|
const orderByComponent = orderBy[i];
|
|
@@ -4798,7 +4907,23 @@ function sortsBeforeDocument(bound, orderBy, doc) {
|
|
|
4798
4907
|
break;
|
|
4799
4908
|
}
|
|
4800
4909
|
}
|
|
4801
|
-
return
|
|
4910
|
+
return comparison;
|
|
4911
|
+
}
|
|
4912
|
+
/**
|
|
4913
|
+
* Returns true if a document sorts after a bound using the provided sort
|
|
4914
|
+
* order.
|
|
4915
|
+
*/
|
|
4916
|
+
function boundSortsAfterDocument(bound, orderBy, doc) {
|
|
4917
|
+
const comparison = boundCompareToDocument(bound, orderBy, doc);
|
|
4918
|
+
return bound.inclusive ? comparison >= 0 : comparison > 0;
|
|
4919
|
+
}
|
|
4920
|
+
/**
|
|
4921
|
+
* Returns true if a document sorts before a bound using the provided sort
|
|
4922
|
+
* order.
|
|
4923
|
+
*/
|
|
4924
|
+
function boundSortsBeforeDocument(bound, orderBy, doc) {
|
|
4925
|
+
const comparison = boundCompareToDocument(bound, orderBy, doc);
|
|
4926
|
+
return bound.inclusive ? comparison <= 0 : comparison < 0;
|
|
4802
4927
|
}
|
|
4803
4928
|
function boundEquals(left, right) {
|
|
4804
4929
|
if (left === null) {
|
|
@@ -4807,7 +4932,7 @@ function boundEquals(left, right) {
|
|
|
4807
4932
|
else if (right === null) {
|
|
4808
4933
|
return false;
|
|
4809
4934
|
}
|
|
4810
|
-
if (left.
|
|
4935
|
+
if (left.inclusive !== right.inclusive ||
|
|
4811
4936
|
left.position.length !== right.position.length) {
|
|
4812
4937
|
return false;
|
|
4813
4938
|
}
|
|
@@ -5011,10 +5136,10 @@ function queryToTarget(query) {
|
|
|
5011
5136
|
}
|
|
5012
5137
|
// We need to swap the cursors to match the now-flipped query ordering.
|
|
5013
5138
|
const startAt = queryImpl.endAt
|
|
5014
|
-
? new Bound(queryImpl.endAt.position, !queryImpl.endAt.
|
|
5139
|
+
? new Bound(queryImpl.endAt.position, !queryImpl.endAt.inclusive)
|
|
5015
5140
|
: null;
|
|
5016
5141
|
const endAt = queryImpl.startAt
|
|
5017
|
-
? new Bound(queryImpl.startAt.position, !queryImpl.startAt.
|
|
5142
|
+
? new Bound(queryImpl.startAt.position, !queryImpl.startAt.inclusive)
|
|
5018
5143
|
: null;
|
|
5019
5144
|
// Now return as a LimitType.First query.
|
|
5020
5145
|
queryImpl.memoizedTarget = newTarget(queryImpl.path, queryImpl.collectionGroup, orderBys, queryImpl.filters, queryImpl.limit, startAt, endAt);
|
|
@@ -5102,11 +5227,11 @@ function queryMatchesFilters(query, doc) {
|
|
|
5102
5227
|
/** Makes sure a document is within the bounds, if provided. */
|
|
5103
5228
|
function queryMatchesBounds(query, doc) {
|
|
5104
5229
|
if (query.startAt &&
|
|
5105
|
-
!
|
|
5230
|
+
!boundSortsBeforeDocument(query.startAt, queryOrderBy(query), doc)) {
|
|
5106
5231
|
return false;
|
|
5107
5232
|
}
|
|
5108
5233
|
if (query.endAt &&
|
|
5109
|
-
|
|
5234
|
+
!boundSortsAfterDocument(query.endAt, queryOrderBy(query), doc)) {
|
|
5110
5235
|
return false;
|
|
5111
5236
|
}
|
|
5112
5237
|
return true;
|
|
@@ -7985,10 +8110,10 @@ function toQueryTarget(serializer, target) {
|
|
|
7985
8110
|
result.structuredQuery.limit = limit;
|
|
7986
8111
|
}
|
|
7987
8112
|
if (target.startAt) {
|
|
7988
|
-
result.structuredQuery.startAt =
|
|
8113
|
+
result.structuredQuery.startAt = toStartAtCursor(target.startAt);
|
|
7989
8114
|
}
|
|
7990
8115
|
if (target.endAt) {
|
|
7991
|
-
result.structuredQuery.endAt =
|
|
8116
|
+
result.structuredQuery.endAt = toEndAtCursor(target.endAt);
|
|
7992
8117
|
}
|
|
7993
8118
|
return result;
|
|
7994
8119
|
}
|
|
@@ -8021,11 +8146,11 @@ function convertQueryTargetToQuery(target) {
|
|
|
8021
8146
|
}
|
|
8022
8147
|
let startAt = null;
|
|
8023
8148
|
if (query.startAt) {
|
|
8024
|
-
startAt =
|
|
8149
|
+
startAt = fromStartAtCursor(query.startAt);
|
|
8025
8150
|
}
|
|
8026
8151
|
let endAt = null;
|
|
8027
8152
|
if (query.endAt) {
|
|
8028
|
-
endAt =
|
|
8153
|
+
endAt = fromEndAtCursor(query.endAt);
|
|
8029
8154
|
}
|
|
8030
8155
|
return newQuery(path, collectionGroup, orderBy, filterBy, limit, "F" /* First */, startAt, endAt);
|
|
8031
8156
|
}
|
|
@@ -8116,16 +8241,27 @@ function toOrder(orderBys) {
|
|
|
8116
8241
|
function fromOrder(orderBys) {
|
|
8117
8242
|
return orderBys.map(order => fromPropertyOrder(order));
|
|
8118
8243
|
}
|
|
8119
|
-
function
|
|
8244
|
+
function toStartAtCursor(cursor) {
|
|
8120
8245
|
return {
|
|
8121
|
-
before: cursor.
|
|
8246
|
+
before: cursor.inclusive,
|
|
8122
8247
|
values: cursor.position
|
|
8123
8248
|
};
|
|
8124
8249
|
}
|
|
8125
|
-
function
|
|
8126
|
-
|
|
8250
|
+
function toEndAtCursor(cursor) {
|
|
8251
|
+
return {
|
|
8252
|
+
before: !cursor.inclusive,
|
|
8253
|
+
values: cursor.position
|
|
8254
|
+
};
|
|
8255
|
+
}
|
|
8256
|
+
function fromStartAtCursor(cursor) {
|
|
8257
|
+
const inclusive = !!cursor.before;
|
|
8258
|
+
const position = cursor.values || [];
|
|
8259
|
+
return new Bound(position, inclusive);
|
|
8260
|
+
}
|
|
8261
|
+
function fromEndAtCursor(cursor) {
|
|
8262
|
+
const inclusive = !cursor.before;
|
|
8127
8263
|
const position = cursor.values || [];
|
|
8128
|
-
return new Bound(position,
|
|
8264
|
+
return new Bound(position, inclusive);
|
|
8129
8265
|
}
|
|
8130
8266
|
// visible for testing
|
|
8131
8267
|
function toDirection(dir) {
|
|
@@ -8589,6 +8725,19 @@ function fromBundleMetadata(metadata) {
|
|
|
8589
8725
|
version: metadata.version,
|
|
8590
8726
|
createTime: fromVersion(metadata.createTime)
|
|
8591
8727
|
};
|
|
8728
|
+
}
|
|
8729
|
+
function toDbIndexConfiguration(index) {
|
|
8730
|
+
return new DbIndexConfiguration(index.indexId, index.collectionGroup, index.fields.map(s => [s.fieldPath.canonicalString(), s.kind]));
|
|
8731
|
+
}
|
|
8732
|
+
function fromDbIndexConfiguration(index, state) {
|
|
8733
|
+
const decodedState = state
|
|
8734
|
+
? new IndexState(state.sequenceNumber, new IndexOffset(fromDbTimestamp(state.readTime), new DocumentKey(decodeResourcePath(state.documentKey)), state.largestBatchId))
|
|
8735
|
+
: IndexState.empty();
|
|
8736
|
+
const decodedSegments = index.fields.map(([fieldPath, kind]) => new IndexSegment(FieldPath$1.fromServerFormat(fieldPath), kind));
|
|
8737
|
+
return new FieldIndex(index.indexId, index.collectionGroup, decodedSegments, decodedState);
|
|
8738
|
+
}
|
|
8739
|
+
function toDbIndexState(indexId, user, sequenceNumber, offset) {
|
|
8740
|
+
return new DbIndexState(indexId, user.uid || '', sequenceNumber, toDbTimestamp(offset.readTime), encodeResourcePath(offset.documentKey.path), offset.largestBatchId);
|
|
8592
8741
|
}
|
|
8593
8742
|
|
|
8594
8743
|
/**
|
|
@@ -8678,6 +8827,38 @@ class MemoryIndexManager {
|
|
|
8678
8827
|
getCollectionParents(transaction, collectionId) {
|
|
8679
8828
|
return PersistencePromise.resolve(this.collectionParentIndex.getEntries(collectionId));
|
|
8680
8829
|
}
|
|
8830
|
+
addFieldIndex(transaction, index) {
|
|
8831
|
+
// Field indices are not supported with memory persistence.
|
|
8832
|
+
return PersistencePromise.resolve();
|
|
8833
|
+
}
|
|
8834
|
+
deleteFieldIndex(transaction, index) {
|
|
8835
|
+
// Field indices are not supported with memory persistence.
|
|
8836
|
+
return PersistencePromise.resolve();
|
|
8837
|
+
}
|
|
8838
|
+
getDocumentsMatchingTarget(transaction, fieldIndex, target) {
|
|
8839
|
+
// Field indices are not supported with memory persistence.
|
|
8840
|
+
return PersistencePromise.resolve(documentKeySet());
|
|
8841
|
+
}
|
|
8842
|
+
getFieldIndex(transaction, target) {
|
|
8843
|
+
// Field indices are not supported with memory persistence.
|
|
8844
|
+
return PersistencePromise.resolve(null);
|
|
8845
|
+
}
|
|
8846
|
+
getFieldIndexes(transaction, collectionGroup) {
|
|
8847
|
+
// Field indices are not supported with memory persistence.
|
|
8848
|
+
return PersistencePromise.resolve([]);
|
|
8849
|
+
}
|
|
8850
|
+
getNextCollectionGroupToUpdate(transaction) {
|
|
8851
|
+
// Field indices are not supported with memory persistence.
|
|
8852
|
+
return PersistencePromise.resolve(null);
|
|
8853
|
+
}
|
|
8854
|
+
updateCollectionGroup(transaction, collectionGroup, offset) {
|
|
8855
|
+
// Field indices are not supported with memory persistence.
|
|
8856
|
+
return PersistencePromise.resolve();
|
|
8857
|
+
}
|
|
8858
|
+
updateIndexEntries(transaction, documents) {
|
|
8859
|
+
// Field indices are not supported with memory persistence.
|
|
8860
|
+
return PersistencePromise.resolve();
|
|
8861
|
+
}
|
|
8681
8862
|
}
|
|
8682
8863
|
/**
|
|
8683
8864
|
* Internal implementation of the collection-parent index exposed by MemoryIndexManager.
|
|
@@ -8729,17 +8910,22 @@ class MemoryCollectionParentIndex {
|
|
|
8729
8910
|
*/
|
|
8730
8911
|
/**
|
|
8731
8912
|
* A persisted implementation of IndexManager.
|
|
8913
|
+
*
|
|
8914
|
+
* PORTING NOTE: Unlike iOS and Android, the Web SDK does not memoize index
|
|
8915
|
+
* data as it supports multi-tab access.
|
|
8732
8916
|
*/
|
|
8733
8917
|
class IndexedDbIndexManager {
|
|
8734
|
-
constructor() {
|
|
8918
|
+
constructor(user) {
|
|
8919
|
+
this.user = user;
|
|
8735
8920
|
/**
|
|
8736
8921
|
* An in-memory copy of the index entries we've already written since the SDK
|
|
8737
8922
|
* launched. Used to avoid re-writing the same entry repeatedly.
|
|
8738
8923
|
*
|
|
8739
|
-
* This is *NOT* a complete cache of what's in persistence and so can never be
|
|
8740
|
-
* satisfy reads.
|
|
8924
|
+
* This is *NOT* a complete cache of what's in persistence and so can never be
|
|
8925
|
+
* used to satisfy reads.
|
|
8741
8926
|
*/
|
|
8742
8927
|
this.collectionParentsCache = new MemoryCollectionParentIndex();
|
|
8928
|
+
this.uid = user.uid || '';
|
|
8743
8929
|
}
|
|
8744
8930
|
/**
|
|
8745
8931
|
* Adds a new entry to the collection parent index.
|
|
@@ -8786,6 +8972,85 @@ class IndexedDbIndexManager {
|
|
|
8786
8972
|
return parentPaths;
|
|
8787
8973
|
});
|
|
8788
8974
|
}
|
|
8975
|
+
addFieldIndex(transaction, index) {
|
|
8976
|
+
// TODO(indexing): Verify that the auto-incrementing index ID works in
|
|
8977
|
+
// Safari & Firefox.
|
|
8978
|
+
const indexes = indexConfigurationStore(transaction);
|
|
8979
|
+
const dbIndex = toDbIndexConfiguration(index);
|
|
8980
|
+
delete dbIndex.indexId; // `indexId` is auto-populated by IndexedDb
|
|
8981
|
+
return indexes.add(dbIndex).next();
|
|
8982
|
+
}
|
|
8983
|
+
deleteFieldIndex(transaction, index) {
|
|
8984
|
+
const indexes = indexConfigurationStore(transaction);
|
|
8985
|
+
const states = indexStateStore(transaction);
|
|
8986
|
+
const entries = indexEntriesStore(transaction);
|
|
8987
|
+
return indexes
|
|
8988
|
+
.delete(index.indexId)
|
|
8989
|
+
.next(() => states.delete(IDBKeyRange.bound([index.indexId], [index.indexId + 1],
|
|
8990
|
+
/*lowerOpen=*/ false,
|
|
8991
|
+
/*upperOpen=*/ true)))
|
|
8992
|
+
.next(() => entries.delete(IDBKeyRange.bound([index.indexId], [index.indexId + 1],
|
|
8993
|
+
/*lowerOpen=*/ false,
|
|
8994
|
+
/*upperOpen=*/ true)));
|
|
8995
|
+
}
|
|
8996
|
+
getDocumentsMatchingTarget(transaction, fieldIndex, target) {
|
|
8997
|
+
// TODO(indexing): Implement
|
|
8998
|
+
return PersistencePromise.resolve(documentKeySet());
|
|
8999
|
+
}
|
|
9000
|
+
getFieldIndex(transaction, target) {
|
|
9001
|
+
// TODO(indexing): Implement
|
|
9002
|
+
return PersistencePromise.resolve(null);
|
|
9003
|
+
}
|
|
9004
|
+
getFieldIndexes(transaction, collectionGroup) {
|
|
9005
|
+
const indexes = indexConfigurationStore(transaction);
|
|
9006
|
+
const states = indexStateStore(transaction);
|
|
9007
|
+
return (collectionGroup
|
|
9008
|
+
? indexes.loadAll(DbIndexConfiguration.collectionGroupIndex, IDBKeyRange.bound(collectionGroup, collectionGroup))
|
|
9009
|
+
: indexes.loadAll()).next(indexConfigs => {
|
|
9010
|
+
const result = [];
|
|
9011
|
+
return PersistencePromise.forEach(indexConfigs, (indexConfig) => {
|
|
9012
|
+
return states
|
|
9013
|
+
.get([indexConfig.indexId, this.uid])
|
|
9014
|
+
.next(indexState => {
|
|
9015
|
+
result.push(fromDbIndexConfiguration(indexConfig, indexState));
|
|
9016
|
+
});
|
|
9017
|
+
}).next(() => result);
|
|
9018
|
+
});
|
|
9019
|
+
}
|
|
9020
|
+
getNextCollectionGroupToUpdate(transaction) {
|
|
9021
|
+
return this.getFieldIndexes(transaction).next(indexes => {
|
|
9022
|
+
if (indexes.length === 0) {
|
|
9023
|
+
return null;
|
|
9024
|
+
}
|
|
9025
|
+
indexes.sort((l, r) => l.indexState.sequenceNumber - r.indexState.sequenceNumber);
|
|
9026
|
+
return indexes[0].collectionGroup;
|
|
9027
|
+
});
|
|
9028
|
+
}
|
|
9029
|
+
updateCollectionGroup(transaction, collectionGroup, offset) {
|
|
9030
|
+
const indexes = indexConfigurationStore(transaction);
|
|
9031
|
+
const states = indexStateStore(transaction);
|
|
9032
|
+
return this.getNextSequenceNumber(transaction).next(nextSequenceNumber => indexes
|
|
9033
|
+
.loadAll(DbIndexConfiguration.collectionGroupIndex, IDBKeyRange.bound(collectionGroup, collectionGroup))
|
|
9034
|
+
.next(configs => PersistencePromise.forEach(configs, (config) => states.put(toDbIndexState(config.indexId, this.user, nextSequenceNumber, offset)))));
|
|
9035
|
+
}
|
|
9036
|
+
updateIndexEntries(transaction, documents) {
|
|
9037
|
+
// TODO(indexing): Implement
|
|
9038
|
+
return PersistencePromise.resolve();
|
|
9039
|
+
}
|
|
9040
|
+
getNextSequenceNumber(transaction) {
|
|
9041
|
+
let nextSequenceNumber = 1;
|
|
9042
|
+
const states = indexStateStore(transaction);
|
|
9043
|
+
return states
|
|
9044
|
+
.iterate({
|
|
9045
|
+
index: DbIndexState.sequenceNumberIndex,
|
|
9046
|
+
reverse: true,
|
|
9047
|
+
range: IDBKeyRange.upperBound([this.uid, Number.MAX_SAFE_INTEGER])
|
|
9048
|
+
}, (_, state, controller) => {
|
|
9049
|
+
controller.done();
|
|
9050
|
+
nextSequenceNumber = state.sequenceNumber + 1;
|
|
9051
|
+
})
|
|
9052
|
+
.next(() => nextSequenceNumber);
|
|
9053
|
+
}
|
|
8789
9054
|
}
|
|
8790
9055
|
/**
|
|
8791
9056
|
* Helper to get a typed SimpleDbStore for the collectionParents
|
|
@@ -8793,6 +9058,24 @@ class IndexedDbIndexManager {
|
|
|
8793
9058
|
*/
|
|
8794
9059
|
function collectionParentsStore(txn) {
|
|
8795
9060
|
return getStore(txn, DbCollectionParent.store);
|
|
9061
|
+
}
|
|
9062
|
+
/**
|
|
9063
|
+
* Helper to get a typed SimpleDbStore for the index entry object store.
|
|
9064
|
+
*/
|
|
9065
|
+
function indexEntriesStore(txn) {
|
|
9066
|
+
return getStore(txn, DbIndexEntry.store);
|
|
9067
|
+
}
|
|
9068
|
+
/**
|
|
9069
|
+
* Helper to get a typed SimpleDbStore for the index configuration object store.
|
|
9070
|
+
*/
|
|
9071
|
+
function indexConfigurationStore(txn) {
|
|
9072
|
+
return getStore(txn, DbIndexConfiguration.store);
|
|
9073
|
+
}
|
|
9074
|
+
/**
|
|
9075
|
+
* Helper to get a typed SimpleDbStore for the index state object store.
|
|
9076
|
+
*/
|
|
9077
|
+
function indexStateStore(txn) {
|
|
9078
|
+
return getStore(txn, DbIndexState.store);
|
|
8796
9079
|
}
|
|
8797
9080
|
|
|
8798
9081
|
/**
|
|
@@ -10262,12 +10545,10 @@ class RemoteDocumentChangeBuffer {
|
|
|
10262
10545
|
* `newIndexedDbRemoteDocumentCache()`.
|
|
10263
10546
|
*/
|
|
10264
10547
|
class IndexedDbRemoteDocumentCacheImpl {
|
|
10265
|
-
|
|
10266
|
-
* @param serializer - The document serializer.
|
|
10267
|
-
* @param indexManager - The query indexes that need to be maintained.
|
|
10268
|
-
*/
|
|
10269
|
-
constructor(serializer, indexManager) {
|
|
10548
|
+
constructor(serializer) {
|
|
10270
10549
|
this.serializer = serializer;
|
|
10550
|
+
}
|
|
10551
|
+
setIndexManager(indexManager) {
|
|
10271
10552
|
this.indexManager = indexManager;
|
|
10272
10553
|
}
|
|
10273
10554
|
/**
|
|
@@ -10389,21 +10670,21 @@ class IndexedDbRemoteDocumentCacheImpl {
|
|
|
10389
10670
|
}
|
|
10390
10671
|
});
|
|
10391
10672
|
}
|
|
10392
|
-
|
|
10673
|
+
getAll(transaction, collection, sinceReadTime) {
|
|
10393
10674
|
let results = mutableDocumentMap();
|
|
10394
|
-
const immediateChildrenPathLength =
|
|
10675
|
+
const immediateChildrenPathLength = collection.length + 1;
|
|
10395
10676
|
const iterationOptions = {};
|
|
10396
10677
|
if (sinceReadTime.isEqual(SnapshotVersion.min())) {
|
|
10397
10678
|
// Documents are ordered by key, so we can use a prefix scan to narrow
|
|
10398
10679
|
// down the documents we need to match the query against.
|
|
10399
|
-
const startKey =
|
|
10680
|
+
const startKey = collection.toArray();
|
|
10400
10681
|
iterationOptions.range = IDBKeyRange.lowerBound(startKey);
|
|
10401
10682
|
}
|
|
10402
10683
|
else {
|
|
10403
10684
|
// Execute an index-free query and filter by read time. This is safe
|
|
10404
10685
|
// since all document changes to queries that have a
|
|
10405
10686
|
// lastLimboFreeSnapshotVersion (`sinceReadTime`) have a read time set.
|
|
10406
|
-
const collectionKey =
|
|
10687
|
+
const collectionKey = collection.toArray();
|
|
10407
10688
|
const readTimeKey = toDbTimestampKey(sinceReadTime);
|
|
10408
10689
|
iterationOptions.range = IDBKeyRange.lowerBound([collectionKey, readTimeKey],
|
|
10409
10690
|
/* open= */ true);
|
|
@@ -10420,12 +10701,12 @@ class IndexedDbRemoteDocumentCacheImpl {
|
|
|
10420
10701
|
return;
|
|
10421
10702
|
}
|
|
10422
10703
|
const document = this.maybeDecodeDocument(DocumentKey.fromSegments(key), dbRemoteDoc);
|
|
10423
|
-
if (
|
|
10424
|
-
control.done();
|
|
10425
|
-
}
|
|
10426
|
-
else if (queryMatches(query, document)) {
|
|
10704
|
+
if (collection.isPrefixOf(document.key.path)) {
|
|
10427
10705
|
results = results.insert(document.key, document);
|
|
10428
10706
|
}
|
|
10707
|
+
else {
|
|
10708
|
+
control.done();
|
|
10709
|
+
}
|
|
10429
10710
|
})
|
|
10430
10711
|
.next(() => results);
|
|
10431
10712
|
}
|
|
@@ -10463,14 +10744,9 @@ class IndexedDbRemoteDocumentCacheImpl {
|
|
|
10463
10744
|
return MutableDocument.newInvalidDocument(documentKey);
|
|
10464
10745
|
}
|
|
10465
10746
|
}
|
|
10466
|
-
/**
|
|
10467
|
-
|
|
10468
|
-
|
|
10469
|
-
* @param serializer - The document serializer.
|
|
10470
|
-
* @param indexManager - The query indexes that need to be maintained.
|
|
10471
|
-
*/
|
|
10472
|
-
function newIndexedDbRemoteDocumentCache(serializer, indexManager) {
|
|
10473
|
-
return new IndexedDbRemoteDocumentCacheImpl(serializer, indexManager);
|
|
10747
|
+
/** Creates a new IndexedDbRemoteDocumentCache. */
|
|
10748
|
+
function newIndexedDbRemoteDocumentCache(serializer) {
|
|
10749
|
+
return new IndexedDbRemoteDocumentCacheImpl(serializer);
|
|
10474
10750
|
}
|
|
10475
10751
|
/**
|
|
10476
10752
|
* Returns the set of documents that have changed since the specified read
|
|
@@ -10637,9 +10913,6 @@ class SchemaConverter {
|
|
|
10637
10913
|
* and local feature development.
|
|
10638
10914
|
*/
|
|
10639
10915
|
createOrUpgrade(db, txn, fromVersion, toVersion) {
|
|
10640
|
-
hardAssert(fromVersion < toVersion &&
|
|
10641
|
-
fromVersion >= 0 &&
|
|
10642
|
-
toVersion <= SCHEMA_VERSION);
|
|
10643
10916
|
const simpleDbTransaction = new SimpleDbTransaction('createOrUpgrade', txn);
|
|
10644
10917
|
if (fromVersion < 1 && toVersion >= 1) {
|
|
10645
10918
|
createPrimaryClientStore(db);
|
|
@@ -10706,6 +10979,11 @@ class SchemaConverter {
|
|
|
10706
10979
|
createNamedQueriesStore(db);
|
|
10707
10980
|
});
|
|
10708
10981
|
}
|
|
10982
|
+
if (fromVersion < 12 && toVersion >= 12) {
|
|
10983
|
+
p = p.next(() => {
|
|
10984
|
+
createFieldIndex(db);
|
|
10985
|
+
});
|
|
10986
|
+
}
|
|
10709
10987
|
return p;
|
|
10710
10988
|
}
|
|
10711
10989
|
addDocumentGlobal(txn) {
|
|
@@ -10912,6 +11190,20 @@ function createNamedQueriesStore(db) {
|
|
|
10912
11190
|
db.createObjectStore(DbNamedQuery.store, {
|
|
10913
11191
|
keyPath: DbNamedQuery.keyPath
|
|
10914
11192
|
});
|
|
11193
|
+
}
|
|
11194
|
+
function createFieldIndex(db) {
|
|
11195
|
+
const indexConfiguratioStore = db.createObjectStore(DbIndexConfiguration.store, {
|
|
11196
|
+
keyPath: DbIndexConfiguration.keyPath,
|
|
11197
|
+
autoIncrement: true
|
|
11198
|
+
});
|
|
11199
|
+
indexConfiguratioStore.createIndex(DbIndexConfiguration.collectionGroupIndex, DbIndexConfiguration.collectionGroupIndexPath, { unique: false });
|
|
11200
|
+
const indexStateStore = db.createObjectStore(DbIndexState.store, {
|
|
11201
|
+
keyPath: DbIndexState.keyPath
|
|
11202
|
+
});
|
|
11203
|
+
indexStateStore.createIndex(DbIndexState.sequenceNumberIndex, DbIndexState.sequenceNumberIndexPath, { unique: false });
|
|
11204
|
+
db.createObjectStore(DbIndexEntry.store, {
|
|
11205
|
+
keyPath: DbIndexEntry.keyPath
|
|
11206
|
+
});
|
|
10915
11207
|
}
|
|
10916
11208
|
|
|
10917
11209
|
/**
|
|
@@ -11023,7 +11315,7 @@ class IndexedDbPersistence {
|
|
|
11023
11315
|
* If set to true, forcefully obtains database access. Existing tabs will
|
|
11024
11316
|
* no longer be able to access IndexedDB.
|
|
11025
11317
|
*/
|
|
11026
|
-
forceOwningTab) {
|
|
11318
|
+
forceOwningTab, schemaVersion = SCHEMA_VERSION) {
|
|
11027
11319
|
this.allowTabSynchronization = allowTabSynchronization;
|
|
11028
11320
|
this.persistenceKey = persistenceKey;
|
|
11029
11321
|
this.clientId = clientId;
|
|
@@ -11032,6 +11324,7 @@ class IndexedDbPersistence {
|
|
|
11032
11324
|
this.document = document;
|
|
11033
11325
|
this.sequenceNumberSyncer = sequenceNumberSyncer;
|
|
11034
11326
|
this.forceOwningTab = forceOwningTab;
|
|
11327
|
+
this.schemaVersion = schemaVersion;
|
|
11035
11328
|
this.listenSequence = null;
|
|
11036
11329
|
this._started = false;
|
|
11037
11330
|
this.isPrimary = false;
|
|
@@ -11053,10 +11346,9 @@ class IndexedDbPersistence {
|
|
|
11053
11346
|
this.referenceDelegate = new IndexedDbLruDelegateImpl(this, lruParams);
|
|
11054
11347
|
this.dbName = persistenceKey + MAIN_DATABASE;
|
|
11055
11348
|
this.serializer = new LocalSerializer(serializer);
|
|
11056
|
-
this.simpleDb = new SimpleDb(this.dbName,
|
|
11349
|
+
this.simpleDb = new SimpleDb(this.dbName, this.schemaVersion, new SchemaConverter(this.serializer));
|
|
11057
11350
|
this.targetCache = new IndexedDbTargetCache(this.referenceDelegate, this.serializer);
|
|
11058
|
-
this.
|
|
11059
|
-
this.remoteDocumentCache = newIndexedDbRemoteDocumentCache(this.serializer, this.indexManager);
|
|
11351
|
+
this.remoteDocumentCache = newIndexedDbRemoteDocumentCache(this.serializer);
|
|
11060
11352
|
this.bundleCache = new IndexedDbBundleCache();
|
|
11061
11353
|
if (this.window && this.window.localStorage) {
|
|
11062
11354
|
this.webStorage = this.window.localStorage;
|
|
@@ -11392,8 +11684,8 @@ class IndexedDbPersistence {
|
|
|
11392
11684
|
get started() {
|
|
11393
11685
|
return this._started;
|
|
11394
11686
|
}
|
|
11395
|
-
getMutationQueue(user) {
|
|
11396
|
-
return IndexedDbMutationQueue.forUser(user, this.serializer,
|
|
11687
|
+
getMutationQueue(user, indexManager) {
|
|
11688
|
+
return IndexedDbMutationQueue.forUser(user, this.serializer, indexManager, this.referenceDelegate);
|
|
11397
11689
|
}
|
|
11398
11690
|
getTargetCache() {
|
|
11399
11691
|
return this.targetCache;
|
|
@@ -11401,8 +11693,8 @@ class IndexedDbPersistence {
|
|
|
11401
11693
|
getRemoteDocumentCache() {
|
|
11402
11694
|
return this.remoteDocumentCache;
|
|
11403
11695
|
}
|
|
11404
|
-
getIndexManager() {
|
|
11405
|
-
return
|
|
11696
|
+
getIndexManager(user) {
|
|
11697
|
+
return new IndexedDbIndexManager(user);
|
|
11406
11698
|
}
|
|
11407
11699
|
getBundleCache() {
|
|
11408
11700
|
return this.bundleCache;
|
|
@@ -11410,11 +11702,12 @@ class IndexedDbPersistence {
|
|
|
11410
11702
|
runTransaction(action, mode, transactionOperation) {
|
|
11411
11703
|
logDebug(LOG_TAG$d, 'Starting transaction:', action);
|
|
11412
11704
|
const simpleDbMode = mode === 'readonly' ? 'readonly' : 'readwrite';
|
|
11705
|
+
const objectStores = getObjectStores(this.schemaVersion);
|
|
11413
11706
|
let persistenceTransaction;
|
|
11414
11707
|
// Do all transactions as readwrite against all object stores, since we
|
|
11415
11708
|
// are the only reader/writer.
|
|
11416
11709
|
return this.simpleDb
|
|
11417
|
-
.runTransaction(action, simpleDbMode,
|
|
11710
|
+
.runTransaction(action, simpleDbMode, objectStores, simpleDbTxn => {
|
|
11418
11711
|
persistenceTransaction = new IndexedDbTransaction(simpleDbTxn, this.listenSequence
|
|
11419
11712
|
? this.listenSequence.next()
|
|
11420
11713
|
: ListenSequence.INVALID);
|
|
@@ -11786,39 +12079,28 @@ class LocalDocumentsView {
|
|
|
11786
12079
|
getDocumentsMatchingCollectionQuery(transaction, query, sinceReadTime) {
|
|
11787
12080
|
// Query the remote documents and overlay mutations.
|
|
11788
12081
|
let results;
|
|
11789
|
-
let mutationBatches;
|
|
11790
12082
|
return this.remoteDocumentCache
|
|
11791
|
-
.
|
|
12083
|
+
.getAll(transaction, query.path, sinceReadTime)
|
|
11792
12084
|
.next(queryResults => {
|
|
11793
12085
|
results = queryResults;
|
|
11794
12086
|
return this.mutationQueue.getAllMutationBatchesAffectingQuery(transaction, query);
|
|
11795
12087
|
})
|
|
11796
|
-
.next(
|
|
11797
|
-
mutationBatches
|
|
11798
|
-
|
|
11799
|
-
|
|
11800
|
-
|
|
11801
|
-
|
|
11802
|
-
|
|
11803
|
-
|
|
11804
|
-
|
|
11805
|
-
|
|
11806
|
-
|
|
11807
|
-
|
|
11808
|
-
|
|
11809
|
-
let document = results.get(key);
|
|
11810
|
-
if (document == null) {
|
|
11811
|
-
// Create invalid document to apply mutations on top of
|
|
11812
|
-
document = MutableDocument.newInvalidDocument(key);
|
|
11813
|
-
results = results.insert(key, document);
|
|
11814
|
-
}
|
|
11815
|
-
mutationApplyToLocalView(mutation, document, batch.localWriteTime);
|
|
11816
|
-
if (!document.isFoundDocument()) {
|
|
11817
|
-
results = results.remove(key);
|
|
11818
|
-
}
|
|
12088
|
+
.next(mutationBatches => {
|
|
12089
|
+
for (const batch of mutationBatches) {
|
|
12090
|
+
for (const mutation of batch.mutations) {
|
|
12091
|
+
const key = mutation.key;
|
|
12092
|
+
let document = results.get(key);
|
|
12093
|
+
if (document == null) {
|
|
12094
|
+
// Create invalid document to apply mutations on top of
|
|
12095
|
+
document = MutableDocument.newInvalidDocument(key);
|
|
12096
|
+
results = results.insert(key, document);
|
|
12097
|
+
}
|
|
12098
|
+
mutationApplyToLocalView(mutation, document, batch.localWriteTime);
|
|
12099
|
+
if (!document.isFoundDocument()) {
|
|
12100
|
+
results = results.remove(key);
|
|
11819
12101
|
}
|
|
11820
12102
|
}
|
|
11821
|
-
}
|
|
12103
|
+
}
|
|
11822
12104
|
})
|
|
11823
12105
|
.next(() => {
|
|
11824
12106
|
// Finally, filter out any documents that don't actually match
|
|
@@ -11831,29 +12113,6 @@ class LocalDocumentsView {
|
|
|
11831
12113
|
return results;
|
|
11832
12114
|
});
|
|
11833
12115
|
}
|
|
11834
|
-
addMissingBaseDocuments(transaction, matchingMutationBatches, existingDocuments) {
|
|
11835
|
-
let missingBaseDocEntriesForPatching = documentKeySet();
|
|
11836
|
-
for (const batch of matchingMutationBatches) {
|
|
11837
|
-
for (const mutation of batch.mutations) {
|
|
11838
|
-
if (mutation instanceof PatchMutation &&
|
|
11839
|
-
existingDocuments.get(mutation.key) === null) {
|
|
11840
|
-
missingBaseDocEntriesForPatching =
|
|
11841
|
-
missingBaseDocEntriesForPatching.add(mutation.key);
|
|
11842
|
-
}
|
|
11843
|
-
}
|
|
11844
|
-
}
|
|
11845
|
-
let mergedDocuments = existingDocuments;
|
|
11846
|
-
return this.remoteDocumentCache
|
|
11847
|
-
.getEntries(transaction, missingBaseDocEntriesForPatching)
|
|
11848
|
-
.next(missingBaseDocs => {
|
|
11849
|
-
missingBaseDocs.forEach((key, doc) => {
|
|
11850
|
-
if (doc.isFoundDocument()) {
|
|
11851
|
-
mergedDocuments = mergedDocuments.insert(key, doc);
|
|
11852
|
-
}
|
|
11853
|
-
});
|
|
11854
|
-
return mergedDocuments;
|
|
11855
|
-
});
|
|
11856
|
-
}
|
|
11857
12116
|
}
|
|
11858
12117
|
|
|
11859
12118
|
/**
|
|
@@ -11912,11 +12171,18 @@ class LocalStoreImpl {
|
|
|
11912
12171
|
* PORTING NOTE: This is only used for multi-tab synchronization.
|
|
11913
12172
|
*/
|
|
11914
12173
|
this.lastDocumentChangeReadTime = SnapshotVersion.min();
|
|
11915
|
-
this.mutationQueue = persistence.getMutationQueue(initialUser);
|
|
11916
12174
|
this.remoteDocuments = persistence.getRemoteDocumentCache();
|
|
11917
12175
|
this.targetCache = persistence.getTargetCache();
|
|
11918
|
-
this.localDocuments = new LocalDocumentsView(this.remoteDocuments, this.mutationQueue, this.persistence.getIndexManager());
|
|
11919
12176
|
this.bundleCache = persistence.getBundleCache();
|
|
12177
|
+
this.initializeUserComponents(initialUser);
|
|
12178
|
+
}
|
|
12179
|
+
initializeUserComponents(user) {
|
|
12180
|
+
// TODO(indexing): Add spec tests that test these components change after a
|
|
12181
|
+
// user change
|
|
12182
|
+
this.indexManager = this.persistence.getIndexManager(user);
|
|
12183
|
+
this.mutationQueue = this.persistence.getMutationQueue(user, this.indexManager);
|
|
12184
|
+
this.localDocuments = new LocalDocumentsView(this.remoteDocuments, this.mutationQueue, this.indexManager);
|
|
12185
|
+
this.remoteDocuments.setIndexManager(this.indexManager);
|
|
11920
12186
|
this.queryEngine.setLocalDocumentsView(this.localDocuments);
|
|
11921
12187
|
}
|
|
11922
12188
|
collectGarbage(garbageCollector) {
|
|
@@ -11938,8 +12204,6 @@ persistence, queryEngine, initialUser, serializer) {
|
|
|
11938
12204
|
// change.
|
|
11939
12205
|
async function localStoreHandleUserChange(localStore, user) {
|
|
11940
12206
|
const localStoreImpl = debugCast(localStore);
|
|
11941
|
-
let newMutationQueue = localStoreImpl.mutationQueue;
|
|
11942
|
-
let newLocalDocuments = localStoreImpl.localDocuments;
|
|
11943
12207
|
const result = await localStoreImpl.persistence.runTransaction('Handle user change', 'readonly', txn => {
|
|
11944
12208
|
// Swap out the mutation queue, grabbing the pending mutation batches
|
|
11945
12209
|
// before and after.
|
|
@@ -11948,11 +12212,8 @@ async function localStoreHandleUserChange(localStore, user) {
|
|
|
11948
12212
|
.getAllMutationBatches(txn)
|
|
11949
12213
|
.next(promisedOldBatches => {
|
|
11950
12214
|
oldBatches = promisedOldBatches;
|
|
11951
|
-
|
|
11952
|
-
|
|
11953
|
-
// MutationQueue.
|
|
11954
|
-
newLocalDocuments = new LocalDocumentsView(localStoreImpl.remoteDocuments, newMutationQueue, localStoreImpl.persistence.getIndexManager());
|
|
11955
|
-
return newMutationQueue.getAllMutationBatches(txn);
|
|
12215
|
+
localStoreImpl.initializeUserComponents(user);
|
|
12216
|
+
return localStoreImpl.mutationQueue.getAllMutationBatches(txn);
|
|
11956
12217
|
})
|
|
11957
12218
|
.next(newBatches => {
|
|
11958
12219
|
const removedBatchIds = [];
|
|
@@ -11973,7 +12234,7 @@ async function localStoreHandleUserChange(localStore, user) {
|
|
|
11973
12234
|
}
|
|
11974
12235
|
// Return the set of all (potentially) changed documents and the list
|
|
11975
12236
|
// of mutation batch IDs that were affected by change.
|
|
11976
|
-
return
|
|
12237
|
+
return localStoreImpl.localDocuments
|
|
11977
12238
|
.getDocuments(txn, changedKeys)
|
|
11978
12239
|
.next(affectedDocuments => {
|
|
11979
12240
|
return {
|
|
@@ -11984,9 +12245,6 @@ async function localStoreHandleUserChange(localStore, user) {
|
|
|
11984
12245
|
});
|
|
11985
12246
|
});
|
|
11986
12247
|
});
|
|
11987
|
-
localStoreImpl.mutationQueue = newMutationQueue;
|
|
11988
|
-
localStoreImpl.localDocuments = newLocalDocuments;
|
|
11989
|
-
localStoreImpl.queryEngine.setLocalDocumentsView(localStoreImpl.localDocuments);
|
|
11990
12248
|
return result;
|
|
11991
12249
|
}
|
|
11992
12250
|
/* Accepts locally generated Mutations and commit them to storage. */
|
|
@@ -13052,14 +13310,16 @@ class MemoryRemoteDocumentCacheImpl {
|
|
|
13052
13310
|
* expected to just return 0 to avoid unnecessarily doing the work of
|
|
13053
13311
|
* calculating the size.
|
|
13054
13312
|
*/
|
|
13055
|
-
constructor(
|
|
13056
|
-
this.indexManager = indexManager;
|
|
13313
|
+
constructor(sizer) {
|
|
13057
13314
|
this.sizer = sizer;
|
|
13058
13315
|
/** Underlying cache of documents and their read times. */
|
|
13059
13316
|
this.docs = documentEntryMap();
|
|
13060
13317
|
/** Size of all cached documents. */
|
|
13061
13318
|
this.size = 0;
|
|
13062
13319
|
}
|
|
13320
|
+
setIndexManager(indexManager) {
|
|
13321
|
+
this.indexManager = indexManager;
|
|
13322
|
+
}
|
|
13063
13323
|
/**
|
|
13064
13324
|
* Adds the supplied entry to the cache and updates the cache size as appropriate.
|
|
13065
13325
|
*
|
|
@@ -13107,21 +13367,22 @@ class MemoryRemoteDocumentCacheImpl {
|
|
|
13107
13367
|
});
|
|
13108
13368
|
return PersistencePromise.resolve(results);
|
|
13109
13369
|
}
|
|
13110
|
-
|
|
13370
|
+
getAll(transaction, collectionPath, sinceReadTime) {
|
|
13111
13371
|
let results = mutableDocumentMap();
|
|
13112
13372
|
// Documents are ordered by key, so we can use a prefix scan to narrow down
|
|
13113
13373
|
// the documents we need to match the query against.
|
|
13114
|
-
const prefix = new DocumentKey(
|
|
13374
|
+
const prefix = new DocumentKey(collectionPath.child(''));
|
|
13115
13375
|
const iterator = this.docs.getIteratorFrom(prefix);
|
|
13116
13376
|
while (iterator.hasNext()) {
|
|
13117
13377
|
const { key, value: { document } } = iterator.getNext();
|
|
13118
|
-
if (!
|
|
13378
|
+
if (!collectionPath.isPrefixOf(key.path)) {
|
|
13119
13379
|
break;
|
|
13120
13380
|
}
|
|
13121
|
-
if (
|
|
13381
|
+
if (key.path.length > collectionPath.length + 1) {
|
|
13382
|
+
// Exclude entries from subcollections.
|
|
13122
13383
|
continue;
|
|
13123
13384
|
}
|
|
13124
|
-
if (
|
|
13385
|
+
if (document.readTime.compareTo(sinceReadTime) <= 0) {
|
|
13125
13386
|
continue;
|
|
13126
13387
|
}
|
|
13127
13388
|
results = results.insert(document.key, document.mutableCopy());
|
|
@@ -13143,13 +13404,12 @@ class MemoryRemoteDocumentCacheImpl {
|
|
|
13143
13404
|
/**
|
|
13144
13405
|
* Creates a new memory-only RemoteDocumentCache.
|
|
13145
13406
|
*
|
|
13146
|
-
* @param indexManager - A class that manages collection group indices.
|
|
13147
13407
|
* @param sizer - Used to assess the size of a document. For eager GC, this is
|
|
13148
13408
|
* expected to just return 0 to avoid unnecessarily doing the work of
|
|
13149
13409
|
* calculating the size.
|
|
13150
13410
|
*/
|
|
13151
|
-
function newMemoryRemoteDocumentCache(
|
|
13152
|
-
return new MemoryRemoteDocumentCacheImpl(
|
|
13411
|
+
function newMemoryRemoteDocumentCache(sizer) {
|
|
13412
|
+
return new MemoryRemoteDocumentCacheImpl(sizer);
|
|
13153
13413
|
}
|
|
13154
13414
|
/**
|
|
13155
13415
|
* Handles the details of adding and updating documents in the MemoryRemoteDocumentCache.
|
|
@@ -13350,7 +13610,7 @@ class MemoryPersistence {
|
|
|
13350
13610
|
this.targetCache = new MemoryTargetCache(this);
|
|
13351
13611
|
const sizer = (doc) => this.referenceDelegate.documentSize(doc);
|
|
13352
13612
|
this.indexManager = new MemoryIndexManager();
|
|
13353
|
-
this.remoteDocumentCache = newMemoryRemoteDocumentCache(
|
|
13613
|
+
this.remoteDocumentCache = newMemoryRemoteDocumentCache(sizer);
|
|
13354
13614
|
this.serializer = new LocalSerializer(serializer);
|
|
13355
13615
|
this.bundleCache = new MemoryBundleCache(this.serializer);
|
|
13356
13616
|
}
|
|
@@ -13371,13 +13631,15 @@ class MemoryPersistence {
|
|
|
13371
13631
|
setNetworkEnabled() {
|
|
13372
13632
|
// No op.
|
|
13373
13633
|
}
|
|
13374
|
-
getIndexManager() {
|
|
13634
|
+
getIndexManager(user) {
|
|
13635
|
+
// We do not currently support indices for memory persistence, so we can
|
|
13636
|
+
// return the same shared instance of the memory index manager.
|
|
13375
13637
|
return this.indexManager;
|
|
13376
13638
|
}
|
|
13377
|
-
getMutationQueue(user) {
|
|
13639
|
+
getMutationQueue(user, indexManager) {
|
|
13378
13640
|
let queue = this.mutationQueues[user.toKey()];
|
|
13379
13641
|
if (!queue) {
|
|
13380
|
-
queue = new MemoryMutationQueue(
|
|
13642
|
+
queue = new MemoryMutationQueue(indexManager, this.referenceDelegate);
|
|
13381
13643
|
this.mutationQueues[user.toKey()] = queue;
|
|
13382
13644
|
}
|
|
13383
13645
|
return queue;
|
|
@@ -20340,12 +20602,12 @@ async function syncEngineListen(syncEngine, query) {
|
|
|
20340
20602
|
}
|
|
20341
20603
|
else {
|
|
20342
20604
|
const targetData = await localStoreAllocateTarget(syncEngineImpl.localStore, queryToTarget(query));
|
|
20343
|
-
const status = syncEngineImpl.sharedClientState.addLocalQueryTarget(targetData.targetId);
|
|
20344
|
-
targetId = targetData.targetId;
|
|
20345
|
-
viewSnapshot = await initializeViewAndComputeSnapshot(syncEngineImpl, query, targetId, status === 'current');
|
|
20346
20605
|
if (syncEngineImpl.isPrimaryClient) {
|
|
20347
20606
|
remoteStoreListen(syncEngineImpl.remoteStore, targetData);
|
|
20348
20607
|
}
|
|
20608
|
+
const status = syncEngineImpl.sharedClientState.addLocalQueryTarget(targetData.targetId);
|
|
20609
|
+
targetId = targetData.targetId;
|
|
20610
|
+
viewSnapshot = await initializeViewAndComputeSnapshot(syncEngineImpl, query, targetId, status === 'current');
|
|
20349
20611
|
}
|
|
20350
20612
|
return viewSnapshot;
|
|
20351
20613
|
}
|
|
@@ -24853,8 +25115,7 @@ class DocumentSnapshot extends DocumentSnapshot$1 {
|
|
|
24853
25115
|
this.metadata = metadata;
|
|
24854
25116
|
}
|
|
24855
25117
|
/**
|
|
24856
|
-
*
|
|
24857
|
-
* exists. True if the document exists.
|
|
25118
|
+
* Returns whether or not the data exists. True if the document exists.
|
|
24858
25119
|
*/
|
|
24859
25120
|
exists() {
|
|
24860
25121
|
return super.exists();
|
|
@@ -25228,51 +25489,53 @@ function limitToLast(limit) {
|
|
|
25228
25489
|
return new QueryLimitConstraint('limitToLast', limit, "L" /* Last */);
|
|
25229
25490
|
}
|
|
25230
25491
|
class QueryStartAtConstraint extends QueryConstraint {
|
|
25231
|
-
constructor(type, _docOrFields,
|
|
25492
|
+
constructor(type, _docOrFields, _inclusive) {
|
|
25232
25493
|
super();
|
|
25233
25494
|
this.type = type;
|
|
25234
25495
|
this._docOrFields = _docOrFields;
|
|
25235
|
-
this.
|
|
25496
|
+
this._inclusive = _inclusive;
|
|
25236
25497
|
}
|
|
25237
25498
|
_apply(query) {
|
|
25238
|
-
const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this.
|
|
25499
|
+
const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._inclusive);
|
|
25239
25500
|
return new Query(query.firestore, query.converter, queryWithStartAt(query._query, bound));
|
|
25240
25501
|
}
|
|
25241
25502
|
}
|
|
25242
25503
|
function startAt(...docOrFields) {
|
|
25243
|
-
return new QueryStartAtConstraint('startAt', docOrFields,
|
|
25504
|
+
return new QueryStartAtConstraint('startAt', docOrFields,
|
|
25505
|
+
/*inclusive=*/ true);
|
|
25244
25506
|
}
|
|
25245
25507
|
function startAfter(...docOrFields) {
|
|
25246
25508
|
return new QueryStartAtConstraint('startAfter', docOrFields,
|
|
25247
|
-
/*
|
|
25509
|
+
/*inclusive=*/ false);
|
|
25248
25510
|
}
|
|
25249
25511
|
class QueryEndAtConstraint extends QueryConstraint {
|
|
25250
|
-
constructor(type, _docOrFields,
|
|
25512
|
+
constructor(type, _docOrFields, _inclusive) {
|
|
25251
25513
|
super();
|
|
25252
25514
|
this.type = type;
|
|
25253
25515
|
this._docOrFields = _docOrFields;
|
|
25254
|
-
this.
|
|
25516
|
+
this._inclusive = _inclusive;
|
|
25255
25517
|
}
|
|
25256
25518
|
_apply(query) {
|
|
25257
|
-
const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this.
|
|
25519
|
+
const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._inclusive);
|
|
25258
25520
|
return new Query(query.firestore, query.converter, queryWithEndAt(query._query, bound));
|
|
25259
25521
|
}
|
|
25260
25522
|
}
|
|
25261
25523
|
function endBefore(...docOrFields) {
|
|
25262
|
-
return new QueryEndAtConstraint('endBefore', docOrFields,
|
|
25524
|
+
return new QueryEndAtConstraint('endBefore', docOrFields,
|
|
25525
|
+
/*inclusive=*/ false);
|
|
25263
25526
|
}
|
|
25264
25527
|
function endAt(...docOrFields) {
|
|
25265
|
-
return new QueryEndAtConstraint('endAt', docOrFields, /*
|
|
25528
|
+
return new QueryEndAtConstraint('endAt', docOrFields, /*inclusive=*/ true);
|
|
25266
25529
|
}
|
|
25267
25530
|
/** Helper function to create a bound from a document or fields */
|
|
25268
|
-
function newQueryBoundFromDocOrFields(query, methodName, docOrFields,
|
|
25531
|
+
function newQueryBoundFromDocOrFields(query, methodName, docOrFields, inclusive) {
|
|
25269
25532
|
docOrFields[0] = getModularInstance(docOrFields[0]);
|
|
25270
25533
|
if (docOrFields[0] instanceof DocumentSnapshot$1) {
|
|
25271
|
-
return newQueryBoundFromDocument(query._query, query.firestore._databaseId, methodName, docOrFields[0]._document,
|
|
25534
|
+
return newQueryBoundFromDocument(query._query, query.firestore._databaseId, methodName, docOrFields[0]._document, inclusive);
|
|
25272
25535
|
}
|
|
25273
25536
|
else {
|
|
25274
25537
|
const reader = newUserDataReader(query.firestore);
|
|
25275
|
-
return newQueryBoundFromFields(query._query, query.firestore._databaseId, reader, methodName, docOrFields,
|
|
25538
|
+
return newQueryBoundFromFields(query._query, query.firestore._databaseId, reader, methodName, docOrFields, inclusive);
|
|
25276
25539
|
}
|
|
25277
25540
|
}
|
|
25278
25541
|
function newQueryFilter(query, methodName, dataReader, databaseId, fieldPath, op, value) {
|
|
@@ -25330,7 +25593,7 @@ function newQueryOrderBy(query, fieldPath, direction) {
|
|
|
25330
25593
|
* of the query or if any of the fields in the order by are an uncommitted
|
|
25331
25594
|
* server timestamp.
|
|
25332
25595
|
*/
|
|
25333
|
-
function newQueryBoundFromDocument(query, databaseId, methodName, doc,
|
|
25596
|
+
function newQueryBoundFromDocument(query, databaseId, methodName, doc, inclusive) {
|
|
25334
25597
|
if (!doc) {
|
|
25335
25598
|
throw new FirestoreError(Code.NOT_FOUND, `Can't use a DocumentSnapshot that doesn't exist for ` +
|
|
25336
25599
|
`${methodName}().`);
|
|
@@ -25367,12 +25630,12 @@ function newQueryBoundFromDocument(query, databaseId, methodName, doc, before) {
|
|
|
25367
25630
|
}
|
|
25368
25631
|
}
|
|
25369
25632
|
}
|
|
25370
|
-
return new Bound(components,
|
|
25633
|
+
return new Bound(components, inclusive);
|
|
25371
25634
|
}
|
|
25372
25635
|
/**
|
|
25373
25636
|
* Converts a list of field values to a `Bound` for the given query.
|
|
25374
25637
|
*/
|
|
25375
|
-
function newQueryBoundFromFields(query, databaseId, dataReader, methodName, values,
|
|
25638
|
+
function newQueryBoundFromFields(query, databaseId, dataReader, methodName, values, inclusive) {
|
|
25376
25639
|
// Use explicit order by's because it has to match the query the user made
|
|
25377
25640
|
const orderBy = query.explicitOrderBy;
|
|
25378
25641
|
if (values.length > orderBy.length) {
|
|
@@ -25409,7 +25672,7 @@ function newQueryBoundFromFields(query, databaseId, dataReader, methodName, valu
|
|
|
25409
25672
|
components.push(wrapped);
|
|
25410
25673
|
}
|
|
25411
25674
|
}
|
|
25412
|
-
return new Bound(components,
|
|
25675
|
+
return new Bound(components, inclusive);
|
|
25413
25676
|
}
|
|
25414
25677
|
/**
|
|
25415
25678
|
* Parses the given `documentIdValue` into a `ReferenceValue`, throwing
|