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