@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.cjs.js
CHANGED
|
@@ -12,7 +12,7 @@ var grpcJs = require('@grpc/grpc-js');
|
|
|
12
12
|
var protoLoader = require('@grpc/proto-loader');
|
|
13
13
|
|
|
14
14
|
const name = "@firebase/firestore";
|
|
15
|
-
const version$1 = "3.4.4-canary.
|
|
15
|
+
const version$1 = "3.4.4-canary.50de44c2e";
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* @license
|
|
@@ -65,7 +65,7 @@ User.GOOGLE_CREDENTIALS = new User('google-credentials-uid');
|
|
|
65
65
|
User.FIRST_PARTY = new User('first-party-uid');
|
|
66
66
|
User.MOCK_USER = new User('mock-user');
|
|
67
67
|
|
|
68
|
-
const version = "9.6.
|
|
68
|
+
const version = "9.6.6-canary.50de44c2e";
|
|
69
69
|
|
|
70
70
|
/**
|
|
71
71
|
* @license
|
|
@@ -1196,23 +1196,6 @@ function decodeResourcePath(path) {
|
|
|
1196
1196
|
}
|
|
1197
1197
|
return new ResourcePath(segments);
|
|
1198
1198
|
}
|
|
1199
|
-
|
|
1200
|
-
/**
|
|
1201
|
-
* @license
|
|
1202
|
-
* Copyright 2017 Google LLC
|
|
1203
|
-
*
|
|
1204
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1205
|
-
* you may not use this file except in compliance with the License.
|
|
1206
|
-
* You may obtain a copy of the License at
|
|
1207
|
-
*
|
|
1208
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1209
|
-
*
|
|
1210
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
1211
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1212
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1213
|
-
* See the License for the specific language governing permissions and
|
|
1214
|
-
* limitations under the License.
|
|
1215
|
-
*/
|
|
1216
1199
|
/**
|
|
1217
1200
|
* Schema Version for the Web client:
|
|
1218
1201
|
* 1. Initial version including Mutation Queue, Query Cache, and Remote
|
|
@@ -1231,6 +1214,7 @@ function decodeResourcePath(path) {
|
|
|
1231
1214
|
* an auto-incrementing ID. This is required for Index-Free queries.
|
|
1232
1215
|
* 10. Rewrite the canonical IDs to the explicit Protobuf-based format.
|
|
1233
1216
|
* 11. Add bundles and named_queries for bundle support.
|
|
1217
|
+
* 12. Add indexing support.
|
|
1234
1218
|
*/
|
|
1235
1219
|
const SCHEMA_VERSION = 11;
|
|
1236
1220
|
/**
|
|
@@ -1757,9 +1741,7 @@ class DbClientMetadata {
|
|
|
1757
1741
|
DbClientMetadata.store = 'clientMetadata';
|
|
1758
1742
|
/** Keys are automatically assigned via the clientId properties. */
|
|
1759
1743
|
DbClientMetadata.keyPath = 'clientId';
|
|
1760
|
-
/**
|
|
1761
|
-
* A object representing a bundle loaded by the SDK.
|
|
1762
|
-
*/
|
|
1744
|
+
/** An object representing a bundle loaded by the SDK. */
|
|
1763
1745
|
class DbBundle {
|
|
1764
1746
|
constructor(
|
|
1765
1747
|
/** The ID of the loaded bundle. */
|
|
@@ -1776,9 +1758,7 @@ class DbBundle {
|
|
|
1776
1758
|
/** Name of the IndexedDb object store. */
|
|
1777
1759
|
DbBundle.store = 'bundles';
|
|
1778
1760
|
DbBundle.keyPath = 'bundleId';
|
|
1779
|
-
/**
|
|
1780
|
-
* A object representing a named query loaded by the SDK via a bundle.
|
|
1781
|
-
*/
|
|
1761
|
+
/** An object representing a named query loaded by the SDK via a bundle. */
|
|
1782
1762
|
class DbNamedQuery {
|
|
1783
1763
|
constructor(
|
|
1784
1764
|
/** The name of the query. */
|
|
@@ -1795,6 +1775,116 @@ class DbNamedQuery {
|
|
|
1795
1775
|
/** Name of the IndexedDb object store. */
|
|
1796
1776
|
DbNamedQuery.store = 'namedQueries';
|
|
1797
1777
|
DbNamedQuery.keyPath = 'name';
|
|
1778
|
+
/** An object representing the global configuration for a field index. */
|
|
1779
|
+
class DbIndexConfiguration {
|
|
1780
|
+
constructor(
|
|
1781
|
+
/**
|
|
1782
|
+
* The index id for this entry. Undefined for indexes that are not yet
|
|
1783
|
+
* persisted.
|
|
1784
|
+
*/
|
|
1785
|
+
indexId,
|
|
1786
|
+
/** The collection group this index belongs to. */
|
|
1787
|
+
collectionGroup,
|
|
1788
|
+
/** The fields to index for this index. */
|
|
1789
|
+
fields) {
|
|
1790
|
+
this.indexId = indexId;
|
|
1791
|
+
this.collectionGroup = collectionGroup;
|
|
1792
|
+
this.fields = fields;
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
/** Name of the IndexedDb object store. */
|
|
1796
|
+
DbIndexConfiguration.store = 'indexConfiguration';
|
|
1797
|
+
DbIndexConfiguration.keyPath = 'indexId';
|
|
1798
|
+
/**
|
|
1799
|
+
* An index that provides access to the index configurations by collection
|
|
1800
|
+
* group.
|
|
1801
|
+
*
|
|
1802
|
+
* PORTING NOTE: iOS and Android maintain this index in-memory, but this is
|
|
1803
|
+
* not possible here as the Web client supports concurrent access to
|
|
1804
|
+
* persistence via multi-tab.
|
|
1805
|
+
*/
|
|
1806
|
+
DbIndexConfiguration.collectionGroupIndex = 'collectionGroupIndex';
|
|
1807
|
+
DbIndexConfiguration.collectionGroupIndexPath = 'collectionGroup';
|
|
1808
|
+
/**
|
|
1809
|
+
* An object describing how up-to-date the index backfill is for each user and
|
|
1810
|
+
* index.
|
|
1811
|
+
*/
|
|
1812
|
+
class DbIndexState {
|
|
1813
|
+
constructor(
|
|
1814
|
+
/** The index id for this entry. */
|
|
1815
|
+
indexId,
|
|
1816
|
+
/** The user id for this entry. */
|
|
1817
|
+
uid,
|
|
1818
|
+
/**
|
|
1819
|
+
* A number that indicates when the index was last updated (relative to
|
|
1820
|
+
* other indexes).
|
|
1821
|
+
*/
|
|
1822
|
+
sequenceNumber,
|
|
1823
|
+
/**
|
|
1824
|
+
* The latest read time that has been indexed by Firestore for this field
|
|
1825
|
+
* index. Set to `{seconds: 0, nanos: 0}` if no documents have been indexed.
|
|
1826
|
+
*/
|
|
1827
|
+
readTime,
|
|
1828
|
+
/**
|
|
1829
|
+
* The last document that has been indexed for this field index. Empty if
|
|
1830
|
+
* no documents have been indexed.
|
|
1831
|
+
*/
|
|
1832
|
+
documentKey,
|
|
1833
|
+
/**
|
|
1834
|
+
* The largest mutation batch id that has been processed for this index. -1
|
|
1835
|
+
* if no mutations have been indexed.
|
|
1836
|
+
*/
|
|
1837
|
+
largestBatchId) {
|
|
1838
|
+
this.indexId = indexId;
|
|
1839
|
+
this.uid = uid;
|
|
1840
|
+
this.sequenceNumber = sequenceNumber;
|
|
1841
|
+
this.readTime = readTime;
|
|
1842
|
+
this.documentKey = documentKey;
|
|
1843
|
+
this.largestBatchId = largestBatchId;
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1846
|
+
/** Name of the IndexedDb object store. */
|
|
1847
|
+
DbIndexState.store = 'indexState';
|
|
1848
|
+
DbIndexState.keyPath = ['indexId', 'uid'];
|
|
1849
|
+
/**
|
|
1850
|
+
* An index that provides access to documents in a collection sorted by last
|
|
1851
|
+
* update time. Used by the backfiller.
|
|
1852
|
+
*
|
|
1853
|
+
* PORTING NOTE: iOS and Android maintain this index in-memory, but this is
|
|
1854
|
+
* not possible here as the Web client supports concurrent access to
|
|
1855
|
+
* persistence via multi-tab.
|
|
1856
|
+
*/
|
|
1857
|
+
DbIndexState.sequenceNumberIndex = 'sequenceNumberIndex';
|
|
1858
|
+
DbIndexState.sequenceNumberIndexPath = ['uid', 'sequenceNumber'];
|
|
1859
|
+
/** An object that stores the encoded entries for all documents and fields. */
|
|
1860
|
+
class DbIndexEntry {
|
|
1861
|
+
constructor(
|
|
1862
|
+
/** The index id for this entry. */
|
|
1863
|
+
indexId,
|
|
1864
|
+
/** The user id for this entry. */
|
|
1865
|
+
uid,
|
|
1866
|
+
/** The encoded array index value for this entry. */
|
|
1867
|
+
arrayValue,
|
|
1868
|
+
/** The encoded directional value for equality and inequality filters. */
|
|
1869
|
+
directionalValue,
|
|
1870
|
+
/** The document key this entry points to. */
|
|
1871
|
+
documentKey) {
|
|
1872
|
+
this.indexId = indexId;
|
|
1873
|
+
this.uid = uid;
|
|
1874
|
+
this.arrayValue = arrayValue;
|
|
1875
|
+
this.directionalValue = directionalValue;
|
|
1876
|
+
this.documentKey = documentKey;
|
|
1877
|
+
}
|
|
1878
|
+
}
|
|
1879
|
+
/** Name of the IndexedDb object store. */
|
|
1880
|
+
DbIndexEntry.store = 'indexEntries';
|
|
1881
|
+
DbIndexEntry.keyPath = [
|
|
1882
|
+
'indexId',
|
|
1883
|
+
'uid',
|
|
1884
|
+
'arrayValue',
|
|
1885
|
+
'directionalValue',
|
|
1886
|
+
'documentKey'
|
|
1887
|
+
];
|
|
1798
1888
|
// Visible for testing
|
|
1799
1889
|
const V1_STORES = [
|
|
1800
1890
|
DbMutationQueue.store,
|
|
@@ -1809,7 +1899,6 @@ const V1_STORES = [
|
|
|
1809
1899
|
// V2 is no longer usable (see comment at top of file)
|
|
1810
1900
|
// Visible for testing
|
|
1811
1901
|
const V3_STORES = V1_STORES;
|
|
1812
|
-
// Visible for testing
|
|
1813
1902
|
// Note: DbRemoteDocumentChanges is no longer used and dropped with v9.
|
|
1814
1903
|
const V4_STORES = [...V3_STORES, DbClientMetadata.store];
|
|
1815
1904
|
// V5 does not change the set of stores.
|
|
@@ -1819,12 +1908,24 @@ const V8_STORES = [...V6_STORES, DbCollectionParent.store];
|
|
|
1819
1908
|
// V9 does not change the set of stores.
|
|
1820
1909
|
// V10 does not change the set of stores.
|
|
1821
1910
|
const V11_STORES = [...V8_STORES, DbBundle.store, DbNamedQuery.store];
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1911
|
+
const V12_STORES = [
|
|
1912
|
+
...V11_STORES,
|
|
1913
|
+
DbIndexConfiguration.store,
|
|
1914
|
+
DbIndexState.store,
|
|
1915
|
+
DbIndexEntry.store
|
|
1916
|
+
];
|
|
1917
|
+
/** Returns the object stores for the provided schema. */
|
|
1918
|
+
function getObjectStores(schemaVersion) {
|
|
1919
|
+
if (schemaVersion === 12) {
|
|
1920
|
+
return V12_STORES;
|
|
1921
|
+
}
|
|
1922
|
+
else if (schemaVersion === 11) {
|
|
1923
|
+
return V11_STORES;
|
|
1924
|
+
}
|
|
1925
|
+
else {
|
|
1926
|
+
fail();
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1828
1929
|
|
|
1829
1930
|
/**
|
|
1830
1931
|
* @license
|
|
@@ -2121,6 +2222,15 @@ class SimpleDbTransaction {
|
|
|
2121
2222
|
this.transaction.abort();
|
|
2122
2223
|
}
|
|
2123
2224
|
}
|
|
2225
|
+
maybeCommit() {
|
|
2226
|
+
// If the browser supports V3 IndexedDB, we invoke commit() explicitly to
|
|
2227
|
+
// speed up index DB processing if the event loop remains blocks.
|
|
2228
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2229
|
+
const maybeV3IndexedDb = this.transaction;
|
|
2230
|
+
if (!this.aborted && typeof maybeV3IndexedDb.commit === 'function') {
|
|
2231
|
+
maybeV3IndexedDb.commit();
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2124
2234
|
/**
|
|
2125
2235
|
* Returns a SimpleDbStore<KeyType, ValueType> for the specified store. All
|
|
2126
2236
|
* operations performed on the SimpleDbStore happen within the context of this
|
|
@@ -2317,6 +2427,10 @@ class SimpleDb {
|
|
|
2317
2427
|
this.db = await this.ensureDb(action);
|
|
2318
2428
|
const transaction = SimpleDbTransaction.open(this.db, action, readonly ? 'readonly' : 'readwrite', objectStores);
|
|
2319
2429
|
const transactionFnResult = transactionFn(transaction)
|
|
2430
|
+
.next(result => {
|
|
2431
|
+
transaction.maybeCommit();
|
|
2432
|
+
return result;
|
|
2433
|
+
})
|
|
2320
2434
|
.catch(error => {
|
|
2321
2435
|
// Abort the transaction if there was an error.
|
|
2322
2436
|
transaction.abort(error);
|
|
@@ -2489,13 +2603,29 @@ class SimpleDbStore {
|
|
|
2489
2603
|
return wrapRequest(request);
|
|
2490
2604
|
}
|
|
2491
2605
|
loadAll(indexOrRange, range) {
|
|
2492
|
-
const
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
return
|
|
2498
|
-
|
|
2606
|
+
const iterateOptions = this.options(indexOrRange, range);
|
|
2607
|
+
// Use `getAll()` if the browser supports IndexedDB v3, as it is roughly
|
|
2608
|
+
// 20% faster. Unfortunately, getAll() does not support custom indices.
|
|
2609
|
+
if (!iterateOptions.index && typeof this.store.getAll === 'function') {
|
|
2610
|
+
const request = this.store.getAll(iterateOptions.range);
|
|
2611
|
+
return new PersistencePromise((resolve, reject) => {
|
|
2612
|
+
request.onerror = (event) => {
|
|
2613
|
+
reject(event.target.error);
|
|
2614
|
+
};
|
|
2615
|
+
request.onsuccess = (event) => {
|
|
2616
|
+
resolve(event.target.result);
|
|
2617
|
+
};
|
|
2618
|
+
});
|
|
2619
|
+
}
|
|
2620
|
+
else {
|
|
2621
|
+
const cursor = this.cursor(iterateOptions);
|
|
2622
|
+
const results = [];
|
|
2623
|
+
return this.iterateCursor(cursor, (key, value) => {
|
|
2624
|
+
results.push(value);
|
|
2625
|
+
}).next(() => {
|
|
2626
|
+
return results;
|
|
2627
|
+
});
|
|
2628
|
+
}
|
|
2499
2629
|
}
|
|
2500
2630
|
deleteAll(indexOrRange, range) {
|
|
2501
2631
|
logDebug(LOG_TAG$g, 'DELETE ALL', this.store.name);
|
|
@@ -4349,12 +4479,12 @@ class FieldIndex {
|
|
|
4349
4479
|
/** The collection ID this index applies to. */
|
|
4350
4480
|
collectionGroup,
|
|
4351
4481
|
/** The field segments for this index. */
|
|
4352
|
-
|
|
4482
|
+
fields,
|
|
4353
4483
|
/** Shows how up-to-date the index is for the current user. */
|
|
4354
4484
|
indexState) {
|
|
4355
4485
|
this.indexId = indexId;
|
|
4356
4486
|
this.collectionGroup = collectionGroup;
|
|
4357
|
-
this.
|
|
4487
|
+
this.fields = fields;
|
|
4358
4488
|
this.indexState = indexState;
|
|
4359
4489
|
}
|
|
4360
4490
|
}
|
|
@@ -4464,27 +4594,29 @@ function newTarget(path, collectionGroup = null, orderBy = [], filters = [], lim
|
|
|
4464
4594
|
function canonifyTarget(target) {
|
|
4465
4595
|
const targetImpl = debugCast(target);
|
|
4466
4596
|
if (targetImpl.memoizedCanonicalId === null) {
|
|
4467
|
-
let
|
|
4597
|
+
let str = targetImpl.path.canonicalString();
|
|
4468
4598
|
if (targetImpl.collectionGroup !== null) {
|
|
4469
|
-
|
|
4599
|
+
str += '|cg:' + targetImpl.collectionGroup;
|
|
4470
4600
|
}
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
|
|
4601
|
+
str += '|f:';
|
|
4602
|
+
str += targetImpl.filters.map(f => canonifyFilter(f)).join(',');
|
|
4603
|
+
str += '|ob:';
|
|
4604
|
+
str += targetImpl.orderBy.map(o => canonifyOrderBy(o)).join(',');
|
|
4475
4605
|
if (!isNullOrUndefined(targetImpl.limit)) {
|
|
4476
|
-
|
|
4477
|
-
|
|
4606
|
+
str += '|l:';
|
|
4607
|
+
str += targetImpl.limit;
|
|
4478
4608
|
}
|
|
4479
4609
|
if (targetImpl.startAt) {
|
|
4480
|
-
|
|
4481
|
-
|
|
4610
|
+
str += '|lb:';
|
|
4611
|
+
str += targetImpl.startAt.inclusive ? 'b:' : 'a:';
|
|
4612
|
+
str += targetImpl.startAt.position.map(p => canonicalId(p)).join(',');
|
|
4482
4613
|
}
|
|
4483
4614
|
if (targetImpl.endAt) {
|
|
4484
|
-
|
|
4485
|
-
|
|
4615
|
+
str += '|ub:';
|
|
4616
|
+
str += targetImpl.endAt.inclusive ? 'a:' : 'b:';
|
|
4617
|
+
str += targetImpl.endAt.position.map(p => canonicalId(p)).join(',');
|
|
4486
4618
|
}
|
|
4487
|
-
targetImpl.memoizedCanonicalId =
|
|
4619
|
+
targetImpl.memoizedCanonicalId = str;
|
|
4488
4620
|
}
|
|
4489
4621
|
return targetImpl.memoizedCanonicalId;
|
|
4490
4622
|
}
|
|
@@ -4507,10 +4639,14 @@ function stringifyTarget(target) {
|
|
|
4507
4639
|
.join(', ')}]`;
|
|
4508
4640
|
}
|
|
4509
4641
|
if (target.startAt) {
|
|
4510
|
-
str += ', startAt: '
|
|
4642
|
+
str += ', startAt: ';
|
|
4643
|
+
str += target.startAt.inclusive ? 'b:' : 'a:';
|
|
4644
|
+
str += target.startAt.position.map(p => canonicalId(p)).join(',');
|
|
4511
4645
|
}
|
|
4512
4646
|
if (target.endAt) {
|
|
4513
|
-
str += ', endAt: '
|
|
4647
|
+
str += ', endAt: ';
|
|
4648
|
+
str += target.endAt.inclusive ? 'a:' : 'b:';
|
|
4649
|
+
str += target.endAt.position.map(p => canonicalId(p)).join(',');
|
|
4514
4650
|
}
|
|
4515
4651
|
return `Target(${str})`;
|
|
4516
4652
|
}
|
|
@@ -4733,7 +4869,6 @@ class ArrayContainsAnyFilter extends FieldFilter {
|
|
|
4733
4869
|
return other.arrayValue.values.some(val => arrayValueContains(this.value.arrayValue, val));
|
|
4734
4870
|
}
|
|
4735
4871
|
}
|
|
4736
|
-
// TODO(indexing): Change Bound.before to "inclusive"
|
|
4737
4872
|
/**
|
|
4738
4873
|
* Represents a bound of a query.
|
|
4739
4874
|
*
|
|
@@ -4749,17 +4884,11 @@ class ArrayContainsAnyFilter extends FieldFilter {
|
|
|
4749
4884
|
* just after the provided values.
|
|
4750
4885
|
*/
|
|
4751
4886
|
class Bound {
|
|
4752
|
-
constructor(position,
|
|
4887
|
+
constructor(position, inclusive) {
|
|
4753
4888
|
this.position = position;
|
|
4754
|
-
this.
|
|
4889
|
+
this.inclusive = inclusive;
|
|
4755
4890
|
}
|
|
4756
4891
|
}
|
|
4757
|
-
function canonifyBound(bound) {
|
|
4758
|
-
// TODO(b/29183165): Make this collision robust.
|
|
4759
|
-
return `${bound.before ? 'b' : 'a'}:${bound.position
|
|
4760
|
-
.map(p => canonicalId(p))
|
|
4761
|
-
.join(',')}`;
|
|
4762
|
-
}
|
|
4763
4892
|
/**
|
|
4764
4893
|
* An ordering on a field, in some Direction. Direction defaults to ASCENDING.
|
|
4765
4894
|
*/
|
|
@@ -4779,11 +4908,7 @@ function stringifyOrderBy(orderBy) {
|
|
|
4779
4908
|
function orderByEquals(left, right) {
|
|
4780
4909
|
return left.dir === right.dir && left.field.isEqual(right.field);
|
|
4781
4910
|
}
|
|
4782
|
-
|
|
4783
|
-
* Returns true if a document sorts before a bound using the provided sort
|
|
4784
|
-
* order.
|
|
4785
|
-
*/
|
|
4786
|
-
function sortsBeforeDocument(bound, orderBy, doc) {
|
|
4911
|
+
function boundCompareToDocument(bound, orderBy, doc) {
|
|
4787
4912
|
let comparison = 0;
|
|
4788
4913
|
for (let i = 0; i < bound.position.length; i++) {
|
|
4789
4914
|
const orderByComponent = orderBy[i];
|
|
@@ -4802,7 +4927,23 @@ function sortsBeforeDocument(bound, orderBy, doc) {
|
|
|
4802
4927
|
break;
|
|
4803
4928
|
}
|
|
4804
4929
|
}
|
|
4805
|
-
return
|
|
4930
|
+
return comparison;
|
|
4931
|
+
}
|
|
4932
|
+
/**
|
|
4933
|
+
* Returns true if a document sorts after a bound using the provided sort
|
|
4934
|
+
* order.
|
|
4935
|
+
*/
|
|
4936
|
+
function boundSortsAfterDocument(bound, orderBy, doc) {
|
|
4937
|
+
const comparison = boundCompareToDocument(bound, orderBy, doc);
|
|
4938
|
+
return bound.inclusive ? comparison >= 0 : comparison > 0;
|
|
4939
|
+
}
|
|
4940
|
+
/**
|
|
4941
|
+
* Returns true if a document sorts before a bound using the provided sort
|
|
4942
|
+
* order.
|
|
4943
|
+
*/
|
|
4944
|
+
function boundSortsBeforeDocument(bound, orderBy, doc) {
|
|
4945
|
+
const comparison = boundCompareToDocument(bound, orderBy, doc);
|
|
4946
|
+
return bound.inclusive ? comparison <= 0 : comparison < 0;
|
|
4806
4947
|
}
|
|
4807
4948
|
function boundEquals(left, right) {
|
|
4808
4949
|
if (left === null) {
|
|
@@ -4811,7 +4952,7 @@ function boundEquals(left, right) {
|
|
|
4811
4952
|
else if (right === null) {
|
|
4812
4953
|
return false;
|
|
4813
4954
|
}
|
|
4814
|
-
if (left.
|
|
4955
|
+
if (left.inclusive !== right.inclusive ||
|
|
4815
4956
|
left.position.length !== right.position.length) {
|
|
4816
4957
|
return false;
|
|
4817
4958
|
}
|
|
@@ -5015,10 +5156,10 @@ function queryToTarget(query) {
|
|
|
5015
5156
|
}
|
|
5016
5157
|
// We need to swap the cursors to match the now-flipped query ordering.
|
|
5017
5158
|
const startAt = queryImpl.endAt
|
|
5018
|
-
? new Bound(queryImpl.endAt.position, !queryImpl.endAt.
|
|
5159
|
+
? new Bound(queryImpl.endAt.position, !queryImpl.endAt.inclusive)
|
|
5019
5160
|
: null;
|
|
5020
5161
|
const endAt = queryImpl.startAt
|
|
5021
|
-
? new Bound(queryImpl.startAt.position, !queryImpl.startAt.
|
|
5162
|
+
? new Bound(queryImpl.startAt.position, !queryImpl.startAt.inclusive)
|
|
5022
5163
|
: null;
|
|
5023
5164
|
// Now return as a LimitType.First query.
|
|
5024
5165
|
queryImpl.memoizedTarget = newTarget(queryImpl.path, queryImpl.collectionGroup, orderBys, queryImpl.filters, queryImpl.limit, startAt, endAt);
|
|
@@ -5106,11 +5247,11 @@ function queryMatchesFilters(query, doc) {
|
|
|
5106
5247
|
/** Makes sure a document is within the bounds, if provided. */
|
|
5107
5248
|
function queryMatchesBounds(query, doc) {
|
|
5108
5249
|
if (query.startAt &&
|
|
5109
|
-
!
|
|
5250
|
+
!boundSortsBeforeDocument(query.startAt, queryOrderBy(query), doc)) {
|
|
5110
5251
|
return false;
|
|
5111
5252
|
}
|
|
5112
5253
|
if (query.endAt &&
|
|
5113
|
-
|
|
5254
|
+
!boundSortsAfterDocument(query.endAt, queryOrderBy(query), doc)) {
|
|
5114
5255
|
return false;
|
|
5115
5256
|
}
|
|
5116
5257
|
return true;
|
|
@@ -7989,10 +8130,10 @@ function toQueryTarget(serializer, target) {
|
|
|
7989
8130
|
result.structuredQuery.limit = limit;
|
|
7990
8131
|
}
|
|
7991
8132
|
if (target.startAt) {
|
|
7992
|
-
result.structuredQuery.startAt =
|
|
8133
|
+
result.structuredQuery.startAt = toStartAtCursor(target.startAt);
|
|
7993
8134
|
}
|
|
7994
8135
|
if (target.endAt) {
|
|
7995
|
-
result.structuredQuery.endAt =
|
|
8136
|
+
result.structuredQuery.endAt = toEndAtCursor(target.endAt);
|
|
7996
8137
|
}
|
|
7997
8138
|
return result;
|
|
7998
8139
|
}
|
|
@@ -8025,11 +8166,11 @@ function convertQueryTargetToQuery(target) {
|
|
|
8025
8166
|
}
|
|
8026
8167
|
let startAt = null;
|
|
8027
8168
|
if (query.startAt) {
|
|
8028
|
-
startAt =
|
|
8169
|
+
startAt = fromStartAtCursor(query.startAt);
|
|
8029
8170
|
}
|
|
8030
8171
|
let endAt = null;
|
|
8031
8172
|
if (query.endAt) {
|
|
8032
|
-
endAt =
|
|
8173
|
+
endAt = fromEndAtCursor(query.endAt);
|
|
8033
8174
|
}
|
|
8034
8175
|
return newQuery(path, collectionGroup, orderBy, filterBy, limit, "F" /* First */, startAt, endAt);
|
|
8035
8176
|
}
|
|
@@ -8120,16 +8261,27 @@ function toOrder(orderBys) {
|
|
|
8120
8261
|
function fromOrder(orderBys) {
|
|
8121
8262
|
return orderBys.map(order => fromPropertyOrder(order));
|
|
8122
8263
|
}
|
|
8123
|
-
function
|
|
8264
|
+
function toStartAtCursor(cursor) {
|
|
8124
8265
|
return {
|
|
8125
|
-
before: cursor.
|
|
8266
|
+
before: cursor.inclusive,
|
|
8126
8267
|
values: cursor.position
|
|
8127
8268
|
};
|
|
8128
8269
|
}
|
|
8129
|
-
function
|
|
8130
|
-
|
|
8270
|
+
function toEndAtCursor(cursor) {
|
|
8271
|
+
return {
|
|
8272
|
+
before: !cursor.inclusive,
|
|
8273
|
+
values: cursor.position
|
|
8274
|
+
};
|
|
8275
|
+
}
|
|
8276
|
+
function fromStartAtCursor(cursor) {
|
|
8277
|
+
const inclusive = !!cursor.before;
|
|
8278
|
+
const position = cursor.values || [];
|
|
8279
|
+
return new Bound(position, inclusive);
|
|
8280
|
+
}
|
|
8281
|
+
function fromEndAtCursor(cursor) {
|
|
8282
|
+
const inclusive = !cursor.before;
|
|
8131
8283
|
const position = cursor.values || [];
|
|
8132
|
-
return new Bound(position,
|
|
8284
|
+
return new Bound(position, inclusive);
|
|
8133
8285
|
}
|
|
8134
8286
|
// visible for testing
|
|
8135
8287
|
function toDirection(dir) {
|
|
@@ -8593,6 +8745,19 @@ function fromBundleMetadata(metadata) {
|
|
|
8593
8745
|
version: metadata.version,
|
|
8594
8746
|
createTime: fromVersion(metadata.createTime)
|
|
8595
8747
|
};
|
|
8748
|
+
}
|
|
8749
|
+
function toDbIndexConfiguration(index) {
|
|
8750
|
+
return new DbIndexConfiguration(index.indexId, index.collectionGroup, index.fields.map(s => [s.fieldPath.canonicalString(), s.kind]));
|
|
8751
|
+
}
|
|
8752
|
+
function fromDbIndexConfiguration(index, state) {
|
|
8753
|
+
const decodedState = state
|
|
8754
|
+
? new IndexState(state.sequenceNumber, new IndexOffset(fromDbTimestamp(state.readTime), new DocumentKey(decodeResourcePath(state.documentKey)), state.largestBatchId))
|
|
8755
|
+
: IndexState.empty();
|
|
8756
|
+
const decodedSegments = index.fields.map(([fieldPath, kind]) => new IndexSegment(FieldPath$1.fromServerFormat(fieldPath), kind));
|
|
8757
|
+
return new FieldIndex(index.indexId, index.collectionGroup, decodedSegments, decodedState);
|
|
8758
|
+
}
|
|
8759
|
+
function toDbIndexState(indexId, user, sequenceNumber, offset) {
|
|
8760
|
+
return new DbIndexState(indexId, user.uid || '', sequenceNumber, toDbTimestamp(offset.readTime), encodeResourcePath(offset.documentKey.path), offset.largestBatchId);
|
|
8596
8761
|
}
|
|
8597
8762
|
|
|
8598
8763
|
/**
|
|
@@ -8682,6 +8847,38 @@ class MemoryIndexManager {
|
|
|
8682
8847
|
getCollectionParents(transaction, collectionId) {
|
|
8683
8848
|
return PersistencePromise.resolve(this.collectionParentIndex.getEntries(collectionId));
|
|
8684
8849
|
}
|
|
8850
|
+
addFieldIndex(transaction, index) {
|
|
8851
|
+
// Field indices are not supported with memory persistence.
|
|
8852
|
+
return PersistencePromise.resolve();
|
|
8853
|
+
}
|
|
8854
|
+
deleteFieldIndex(transaction, index) {
|
|
8855
|
+
// Field indices are not supported with memory persistence.
|
|
8856
|
+
return PersistencePromise.resolve();
|
|
8857
|
+
}
|
|
8858
|
+
getDocumentsMatchingTarget(transaction, fieldIndex, target) {
|
|
8859
|
+
// Field indices are not supported with memory persistence.
|
|
8860
|
+
return PersistencePromise.resolve(documentKeySet());
|
|
8861
|
+
}
|
|
8862
|
+
getFieldIndex(transaction, target) {
|
|
8863
|
+
// Field indices are not supported with memory persistence.
|
|
8864
|
+
return PersistencePromise.resolve(null);
|
|
8865
|
+
}
|
|
8866
|
+
getFieldIndexes(transaction, collectionGroup) {
|
|
8867
|
+
// Field indices are not supported with memory persistence.
|
|
8868
|
+
return PersistencePromise.resolve([]);
|
|
8869
|
+
}
|
|
8870
|
+
getNextCollectionGroupToUpdate(transaction) {
|
|
8871
|
+
// Field indices are not supported with memory persistence.
|
|
8872
|
+
return PersistencePromise.resolve(null);
|
|
8873
|
+
}
|
|
8874
|
+
updateCollectionGroup(transaction, collectionGroup, offset) {
|
|
8875
|
+
// Field indices are not supported with memory persistence.
|
|
8876
|
+
return PersistencePromise.resolve();
|
|
8877
|
+
}
|
|
8878
|
+
updateIndexEntries(transaction, documents) {
|
|
8879
|
+
// Field indices are not supported with memory persistence.
|
|
8880
|
+
return PersistencePromise.resolve();
|
|
8881
|
+
}
|
|
8685
8882
|
}
|
|
8686
8883
|
/**
|
|
8687
8884
|
* Internal implementation of the collection-parent index exposed by MemoryIndexManager.
|
|
@@ -8733,17 +8930,22 @@ class MemoryCollectionParentIndex {
|
|
|
8733
8930
|
*/
|
|
8734
8931
|
/**
|
|
8735
8932
|
* A persisted implementation of IndexManager.
|
|
8933
|
+
*
|
|
8934
|
+
* PORTING NOTE: Unlike iOS and Android, the Web SDK does not memoize index
|
|
8935
|
+
* data as it supports multi-tab access.
|
|
8736
8936
|
*/
|
|
8737
8937
|
class IndexedDbIndexManager {
|
|
8738
|
-
constructor() {
|
|
8938
|
+
constructor(user) {
|
|
8939
|
+
this.user = user;
|
|
8739
8940
|
/**
|
|
8740
8941
|
* An in-memory copy of the index entries we've already written since the SDK
|
|
8741
8942
|
* launched. Used to avoid re-writing the same entry repeatedly.
|
|
8742
8943
|
*
|
|
8743
|
-
* This is *NOT* a complete cache of what's in persistence and so can never be
|
|
8744
|
-
* satisfy reads.
|
|
8944
|
+
* This is *NOT* a complete cache of what's in persistence and so can never be
|
|
8945
|
+
* used to satisfy reads.
|
|
8745
8946
|
*/
|
|
8746
8947
|
this.collectionParentsCache = new MemoryCollectionParentIndex();
|
|
8948
|
+
this.uid = user.uid || '';
|
|
8747
8949
|
}
|
|
8748
8950
|
/**
|
|
8749
8951
|
* Adds a new entry to the collection parent index.
|
|
@@ -8790,6 +8992,85 @@ class IndexedDbIndexManager {
|
|
|
8790
8992
|
return parentPaths;
|
|
8791
8993
|
});
|
|
8792
8994
|
}
|
|
8995
|
+
addFieldIndex(transaction, index) {
|
|
8996
|
+
// TODO(indexing): Verify that the auto-incrementing index ID works in
|
|
8997
|
+
// Safari & Firefox.
|
|
8998
|
+
const indexes = indexConfigurationStore(transaction);
|
|
8999
|
+
const dbIndex = toDbIndexConfiguration(index);
|
|
9000
|
+
delete dbIndex.indexId; // `indexId` is auto-populated by IndexedDb
|
|
9001
|
+
return indexes.add(dbIndex).next();
|
|
9002
|
+
}
|
|
9003
|
+
deleteFieldIndex(transaction, index) {
|
|
9004
|
+
const indexes = indexConfigurationStore(transaction);
|
|
9005
|
+
const states = indexStateStore(transaction);
|
|
9006
|
+
const entries = indexEntriesStore(transaction);
|
|
9007
|
+
return indexes
|
|
9008
|
+
.delete(index.indexId)
|
|
9009
|
+
.next(() => states.delete(IDBKeyRange.bound([index.indexId], [index.indexId + 1],
|
|
9010
|
+
/*lowerOpen=*/ false,
|
|
9011
|
+
/*upperOpen=*/ true)))
|
|
9012
|
+
.next(() => entries.delete(IDBKeyRange.bound([index.indexId], [index.indexId + 1],
|
|
9013
|
+
/*lowerOpen=*/ false,
|
|
9014
|
+
/*upperOpen=*/ true)));
|
|
9015
|
+
}
|
|
9016
|
+
getDocumentsMatchingTarget(transaction, fieldIndex, target) {
|
|
9017
|
+
// TODO(indexing): Implement
|
|
9018
|
+
return PersistencePromise.resolve(documentKeySet());
|
|
9019
|
+
}
|
|
9020
|
+
getFieldIndex(transaction, target) {
|
|
9021
|
+
// TODO(indexing): Implement
|
|
9022
|
+
return PersistencePromise.resolve(null);
|
|
9023
|
+
}
|
|
9024
|
+
getFieldIndexes(transaction, collectionGroup) {
|
|
9025
|
+
const indexes = indexConfigurationStore(transaction);
|
|
9026
|
+
const states = indexStateStore(transaction);
|
|
9027
|
+
return (collectionGroup
|
|
9028
|
+
? indexes.loadAll(DbIndexConfiguration.collectionGroupIndex, IDBKeyRange.bound(collectionGroup, collectionGroup))
|
|
9029
|
+
: indexes.loadAll()).next(indexConfigs => {
|
|
9030
|
+
const result = [];
|
|
9031
|
+
return PersistencePromise.forEach(indexConfigs, (indexConfig) => {
|
|
9032
|
+
return states
|
|
9033
|
+
.get([indexConfig.indexId, this.uid])
|
|
9034
|
+
.next(indexState => {
|
|
9035
|
+
result.push(fromDbIndexConfiguration(indexConfig, indexState));
|
|
9036
|
+
});
|
|
9037
|
+
}).next(() => result);
|
|
9038
|
+
});
|
|
9039
|
+
}
|
|
9040
|
+
getNextCollectionGroupToUpdate(transaction) {
|
|
9041
|
+
return this.getFieldIndexes(transaction).next(indexes => {
|
|
9042
|
+
if (indexes.length === 0) {
|
|
9043
|
+
return null;
|
|
9044
|
+
}
|
|
9045
|
+
indexes.sort((l, r) => l.indexState.sequenceNumber - r.indexState.sequenceNumber);
|
|
9046
|
+
return indexes[0].collectionGroup;
|
|
9047
|
+
});
|
|
9048
|
+
}
|
|
9049
|
+
updateCollectionGroup(transaction, collectionGroup, offset) {
|
|
9050
|
+
const indexes = indexConfigurationStore(transaction);
|
|
9051
|
+
const states = indexStateStore(transaction);
|
|
9052
|
+
return this.getNextSequenceNumber(transaction).next(nextSequenceNumber => indexes
|
|
9053
|
+
.loadAll(DbIndexConfiguration.collectionGroupIndex, IDBKeyRange.bound(collectionGroup, collectionGroup))
|
|
9054
|
+
.next(configs => PersistencePromise.forEach(configs, (config) => states.put(toDbIndexState(config.indexId, this.user, nextSequenceNumber, offset)))));
|
|
9055
|
+
}
|
|
9056
|
+
updateIndexEntries(transaction, documents) {
|
|
9057
|
+
// TODO(indexing): Implement
|
|
9058
|
+
return PersistencePromise.resolve();
|
|
9059
|
+
}
|
|
9060
|
+
getNextSequenceNumber(transaction) {
|
|
9061
|
+
let nextSequenceNumber = 1;
|
|
9062
|
+
const states = indexStateStore(transaction);
|
|
9063
|
+
return states
|
|
9064
|
+
.iterate({
|
|
9065
|
+
index: DbIndexState.sequenceNumberIndex,
|
|
9066
|
+
reverse: true,
|
|
9067
|
+
range: IDBKeyRange.upperBound([this.uid, Number.MAX_SAFE_INTEGER])
|
|
9068
|
+
}, (_, state, controller) => {
|
|
9069
|
+
controller.done();
|
|
9070
|
+
nextSequenceNumber = state.sequenceNumber + 1;
|
|
9071
|
+
})
|
|
9072
|
+
.next(() => nextSequenceNumber);
|
|
9073
|
+
}
|
|
8793
9074
|
}
|
|
8794
9075
|
/**
|
|
8795
9076
|
* Helper to get a typed SimpleDbStore for the collectionParents
|
|
@@ -8797,6 +9078,24 @@ class IndexedDbIndexManager {
|
|
|
8797
9078
|
*/
|
|
8798
9079
|
function collectionParentsStore(txn) {
|
|
8799
9080
|
return getStore(txn, DbCollectionParent.store);
|
|
9081
|
+
}
|
|
9082
|
+
/**
|
|
9083
|
+
* Helper to get a typed SimpleDbStore for the index entry object store.
|
|
9084
|
+
*/
|
|
9085
|
+
function indexEntriesStore(txn) {
|
|
9086
|
+
return getStore(txn, DbIndexEntry.store);
|
|
9087
|
+
}
|
|
9088
|
+
/**
|
|
9089
|
+
* Helper to get a typed SimpleDbStore for the index configuration object store.
|
|
9090
|
+
*/
|
|
9091
|
+
function indexConfigurationStore(txn) {
|
|
9092
|
+
return getStore(txn, DbIndexConfiguration.store);
|
|
9093
|
+
}
|
|
9094
|
+
/**
|
|
9095
|
+
* Helper to get a typed SimpleDbStore for the index state object store.
|
|
9096
|
+
*/
|
|
9097
|
+
function indexStateStore(txn) {
|
|
9098
|
+
return getStore(txn, DbIndexState.store);
|
|
8800
9099
|
}
|
|
8801
9100
|
|
|
8802
9101
|
/**
|
|
@@ -10266,12 +10565,10 @@ class RemoteDocumentChangeBuffer {
|
|
|
10266
10565
|
* `newIndexedDbRemoteDocumentCache()`.
|
|
10267
10566
|
*/
|
|
10268
10567
|
class IndexedDbRemoteDocumentCacheImpl {
|
|
10269
|
-
|
|
10270
|
-
* @param serializer - The document serializer.
|
|
10271
|
-
* @param indexManager - The query indexes that need to be maintained.
|
|
10272
|
-
*/
|
|
10273
|
-
constructor(serializer, indexManager) {
|
|
10568
|
+
constructor(serializer) {
|
|
10274
10569
|
this.serializer = serializer;
|
|
10570
|
+
}
|
|
10571
|
+
setIndexManager(indexManager) {
|
|
10275
10572
|
this.indexManager = indexManager;
|
|
10276
10573
|
}
|
|
10277
10574
|
/**
|
|
@@ -10393,21 +10690,21 @@ class IndexedDbRemoteDocumentCacheImpl {
|
|
|
10393
10690
|
}
|
|
10394
10691
|
});
|
|
10395
10692
|
}
|
|
10396
|
-
|
|
10693
|
+
getAll(transaction, collection, sinceReadTime) {
|
|
10397
10694
|
let results = mutableDocumentMap();
|
|
10398
|
-
const immediateChildrenPathLength =
|
|
10695
|
+
const immediateChildrenPathLength = collection.length + 1;
|
|
10399
10696
|
const iterationOptions = {};
|
|
10400
10697
|
if (sinceReadTime.isEqual(SnapshotVersion.min())) {
|
|
10401
10698
|
// Documents are ordered by key, so we can use a prefix scan to narrow
|
|
10402
10699
|
// down the documents we need to match the query against.
|
|
10403
|
-
const startKey =
|
|
10700
|
+
const startKey = collection.toArray();
|
|
10404
10701
|
iterationOptions.range = IDBKeyRange.lowerBound(startKey);
|
|
10405
10702
|
}
|
|
10406
10703
|
else {
|
|
10407
10704
|
// Execute an index-free query and filter by read time. This is safe
|
|
10408
10705
|
// since all document changes to queries that have a
|
|
10409
10706
|
// lastLimboFreeSnapshotVersion (`sinceReadTime`) have a read time set.
|
|
10410
|
-
const collectionKey =
|
|
10707
|
+
const collectionKey = collection.toArray();
|
|
10411
10708
|
const readTimeKey = toDbTimestampKey(sinceReadTime);
|
|
10412
10709
|
iterationOptions.range = IDBKeyRange.lowerBound([collectionKey, readTimeKey],
|
|
10413
10710
|
/* open= */ true);
|
|
@@ -10424,12 +10721,12 @@ class IndexedDbRemoteDocumentCacheImpl {
|
|
|
10424
10721
|
return;
|
|
10425
10722
|
}
|
|
10426
10723
|
const document = this.maybeDecodeDocument(DocumentKey.fromSegments(key), dbRemoteDoc);
|
|
10427
|
-
if (
|
|
10428
|
-
control.done();
|
|
10429
|
-
}
|
|
10430
|
-
else if (queryMatches(query, document)) {
|
|
10724
|
+
if (collection.isPrefixOf(document.key.path)) {
|
|
10431
10725
|
results = results.insert(document.key, document);
|
|
10432
10726
|
}
|
|
10727
|
+
else {
|
|
10728
|
+
control.done();
|
|
10729
|
+
}
|
|
10433
10730
|
})
|
|
10434
10731
|
.next(() => results);
|
|
10435
10732
|
}
|
|
@@ -10467,14 +10764,9 @@ class IndexedDbRemoteDocumentCacheImpl {
|
|
|
10467
10764
|
return MutableDocument.newInvalidDocument(documentKey);
|
|
10468
10765
|
}
|
|
10469
10766
|
}
|
|
10470
|
-
/**
|
|
10471
|
-
|
|
10472
|
-
|
|
10473
|
-
* @param serializer - The document serializer.
|
|
10474
|
-
* @param indexManager - The query indexes that need to be maintained.
|
|
10475
|
-
*/
|
|
10476
|
-
function newIndexedDbRemoteDocumentCache(serializer, indexManager) {
|
|
10477
|
-
return new IndexedDbRemoteDocumentCacheImpl(serializer, indexManager);
|
|
10767
|
+
/** Creates a new IndexedDbRemoteDocumentCache. */
|
|
10768
|
+
function newIndexedDbRemoteDocumentCache(serializer) {
|
|
10769
|
+
return new IndexedDbRemoteDocumentCacheImpl(serializer);
|
|
10478
10770
|
}
|
|
10479
10771
|
/**
|
|
10480
10772
|
* Returns the set of documents that have changed since the specified read
|
|
@@ -10641,9 +10933,6 @@ class SchemaConverter {
|
|
|
10641
10933
|
* and local feature development.
|
|
10642
10934
|
*/
|
|
10643
10935
|
createOrUpgrade(db, txn, fromVersion, toVersion) {
|
|
10644
|
-
hardAssert(fromVersion < toVersion &&
|
|
10645
|
-
fromVersion >= 0 &&
|
|
10646
|
-
toVersion <= SCHEMA_VERSION);
|
|
10647
10936
|
const simpleDbTransaction = new SimpleDbTransaction('createOrUpgrade', txn);
|
|
10648
10937
|
if (fromVersion < 1 && toVersion >= 1) {
|
|
10649
10938
|
createPrimaryClientStore(db);
|
|
@@ -10710,6 +10999,11 @@ class SchemaConverter {
|
|
|
10710
10999
|
createNamedQueriesStore(db);
|
|
10711
11000
|
});
|
|
10712
11001
|
}
|
|
11002
|
+
if (fromVersion < 12 && toVersion >= 12) {
|
|
11003
|
+
p = p.next(() => {
|
|
11004
|
+
createFieldIndex(db);
|
|
11005
|
+
});
|
|
11006
|
+
}
|
|
10713
11007
|
return p;
|
|
10714
11008
|
}
|
|
10715
11009
|
addDocumentGlobal(txn) {
|
|
@@ -10916,6 +11210,20 @@ function createNamedQueriesStore(db) {
|
|
|
10916
11210
|
db.createObjectStore(DbNamedQuery.store, {
|
|
10917
11211
|
keyPath: DbNamedQuery.keyPath
|
|
10918
11212
|
});
|
|
11213
|
+
}
|
|
11214
|
+
function createFieldIndex(db) {
|
|
11215
|
+
const indexConfiguratioStore = db.createObjectStore(DbIndexConfiguration.store, {
|
|
11216
|
+
keyPath: DbIndexConfiguration.keyPath,
|
|
11217
|
+
autoIncrement: true
|
|
11218
|
+
});
|
|
11219
|
+
indexConfiguratioStore.createIndex(DbIndexConfiguration.collectionGroupIndex, DbIndexConfiguration.collectionGroupIndexPath, { unique: false });
|
|
11220
|
+
const indexStateStore = db.createObjectStore(DbIndexState.store, {
|
|
11221
|
+
keyPath: DbIndexState.keyPath
|
|
11222
|
+
});
|
|
11223
|
+
indexStateStore.createIndex(DbIndexState.sequenceNumberIndex, DbIndexState.sequenceNumberIndexPath, { unique: false });
|
|
11224
|
+
db.createObjectStore(DbIndexEntry.store, {
|
|
11225
|
+
keyPath: DbIndexEntry.keyPath
|
|
11226
|
+
});
|
|
10919
11227
|
}
|
|
10920
11228
|
|
|
10921
11229
|
/**
|
|
@@ -11027,7 +11335,7 @@ class IndexedDbPersistence {
|
|
|
11027
11335
|
* If set to true, forcefully obtains database access. Existing tabs will
|
|
11028
11336
|
* no longer be able to access IndexedDB.
|
|
11029
11337
|
*/
|
|
11030
|
-
forceOwningTab) {
|
|
11338
|
+
forceOwningTab, schemaVersion = SCHEMA_VERSION) {
|
|
11031
11339
|
this.allowTabSynchronization = allowTabSynchronization;
|
|
11032
11340
|
this.persistenceKey = persistenceKey;
|
|
11033
11341
|
this.clientId = clientId;
|
|
@@ -11036,6 +11344,7 @@ class IndexedDbPersistence {
|
|
|
11036
11344
|
this.document = document;
|
|
11037
11345
|
this.sequenceNumberSyncer = sequenceNumberSyncer;
|
|
11038
11346
|
this.forceOwningTab = forceOwningTab;
|
|
11347
|
+
this.schemaVersion = schemaVersion;
|
|
11039
11348
|
this.listenSequence = null;
|
|
11040
11349
|
this._started = false;
|
|
11041
11350
|
this.isPrimary = false;
|
|
@@ -11057,10 +11366,9 @@ class IndexedDbPersistence {
|
|
|
11057
11366
|
this.referenceDelegate = new IndexedDbLruDelegateImpl(this, lruParams);
|
|
11058
11367
|
this.dbName = persistenceKey + MAIN_DATABASE;
|
|
11059
11368
|
this.serializer = new LocalSerializer(serializer);
|
|
11060
|
-
this.simpleDb = new SimpleDb(this.dbName,
|
|
11369
|
+
this.simpleDb = new SimpleDb(this.dbName, this.schemaVersion, new SchemaConverter(this.serializer));
|
|
11061
11370
|
this.targetCache = new IndexedDbTargetCache(this.referenceDelegate, this.serializer);
|
|
11062
|
-
this.
|
|
11063
|
-
this.remoteDocumentCache = newIndexedDbRemoteDocumentCache(this.serializer, this.indexManager);
|
|
11371
|
+
this.remoteDocumentCache = newIndexedDbRemoteDocumentCache(this.serializer);
|
|
11064
11372
|
this.bundleCache = new IndexedDbBundleCache();
|
|
11065
11373
|
if (this.window && this.window.localStorage) {
|
|
11066
11374
|
this.webStorage = this.window.localStorage;
|
|
@@ -11396,8 +11704,8 @@ class IndexedDbPersistence {
|
|
|
11396
11704
|
get started() {
|
|
11397
11705
|
return this._started;
|
|
11398
11706
|
}
|
|
11399
|
-
getMutationQueue(user) {
|
|
11400
|
-
return IndexedDbMutationQueue.forUser(user, this.serializer,
|
|
11707
|
+
getMutationQueue(user, indexManager) {
|
|
11708
|
+
return IndexedDbMutationQueue.forUser(user, this.serializer, indexManager, this.referenceDelegate);
|
|
11401
11709
|
}
|
|
11402
11710
|
getTargetCache() {
|
|
11403
11711
|
return this.targetCache;
|
|
@@ -11405,8 +11713,8 @@ class IndexedDbPersistence {
|
|
|
11405
11713
|
getRemoteDocumentCache() {
|
|
11406
11714
|
return this.remoteDocumentCache;
|
|
11407
11715
|
}
|
|
11408
|
-
getIndexManager() {
|
|
11409
|
-
return
|
|
11716
|
+
getIndexManager(user) {
|
|
11717
|
+
return new IndexedDbIndexManager(user);
|
|
11410
11718
|
}
|
|
11411
11719
|
getBundleCache() {
|
|
11412
11720
|
return this.bundleCache;
|
|
@@ -11414,11 +11722,12 @@ class IndexedDbPersistence {
|
|
|
11414
11722
|
runTransaction(action, mode, transactionOperation) {
|
|
11415
11723
|
logDebug(LOG_TAG$d, 'Starting transaction:', action);
|
|
11416
11724
|
const simpleDbMode = mode === 'readonly' ? 'readonly' : 'readwrite';
|
|
11725
|
+
const objectStores = getObjectStores(this.schemaVersion);
|
|
11417
11726
|
let persistenceTransaction;
|
|
11418
11727
|
// Do all transactions as readwrite against all object stores, since we
|
|
11419
11728
|
// are the only reader/writer.
|
|
11420
11729
|
return this.simpleDb
|
|
11421
|
-
.runTransaction(action, simpleDbMode,
|
|
11730
|
+
.runTransaction(action, simpleDbMode, objectStores, simpleDbTxn => {
|
|
11422
11731
|
persistenceTransaction = new IndexedDbTransaction(simpleDbTxn, this.listenSequence
|
|
11423
11732
|
? this.listenSequence.next()
|
|
11424
11733
|
: ListenSequence.INVALID);
|
|
@@ -11790,39 +12099,28 @@ class LocalDocumentsView {
|
|
|
11790
12099
|
getDocumentsMatchingCollectionQuery(transaction, query, sinceReadTime) {
|
|
11791
12100
|
// Query the remote documents and overlay mutations.
|
|
11792
12101
|
let results;
|
|
11793
|
-
let mutationBatches;
|
|
11794
12102
|
return this.remoteDocumentCache
|
|
11795
|
-
.
|
|
12103
|
+
.getAll(transaction, query.path, sinceReadTime)
|
|
11796
12104
|
.next(queryResults => {
|
|
11797
12105
|
results = queryResults;
|
|
11798
12106
|
return this.mutationQueue.getAllMutationBatchesAffectingQuery(transaction, query);
|
|
11799
12107
|
})
|
|
11800
|
-
.next(
|
|
11801
|
-
mutationBatches
|
|
11802
|
-
|
|
11803
|
-
|
|
11804
|
-
|
|
11805
|
-
|
|
11806
|
-
|
|
11807
|
-
|
|
11808
|
-
|
|
11809
|
-
|
|
11810
|
-
|
|
11811
|
-
|
|
11812
|
-
|
|
11813
|
-
let document = results.get(key);
|
|
11814
|
-
if (document == null) {
|
|
11815
|
-
// Create invalid document to apply mutations on top of
|
|
11816
|
-
document = MutableDocument.newInvalidDocument(key);
|
|
11817
|
-
results = results.insert(key, document);
|
|
11818
|
-
}
|
|
11819
|
-
mutationApplyToLocalView(mutation, document, batch.localWriteTime);
|
|
11820
|
-
if (!document.isFoundDocument()) {
|
|
11821
|
-
results = results.remove(key);
|
|
11822
|
-
}
|
|
12108
|
+
.next(mutationBatches => {
|
|
12109
|
+
for (const batch of mutationBatches) {
|
|
12110
|
+
for (const mutation of batch.mutations) {
|
|
12111
|
+
const key = mutation.key;
|
|
12112
|
+
let document = results.get(key);
|
|
12113
|
+
if (document == null) {
|
|
12114
|
+
// Create invalid document to apply mutations on top of
|
|
12115
|
+
document = MutableDocument.newInvalidDocument(key);
|
|
12116
|
+
results = results.insert(key, document);
|
|
12117
|
+
}
|
|
12118
|
+
mutationApplyToLocalView(mutation, document, batch.localWriteTime);
|
|
12119
|
+
if (!document.isFoundDocument()) {
|
|
12120
|
+
results = results.remove(key);
|
|
11823
12121
|
}
|
|
11824
12122
|
}
|
|
11825
|
-
}
|
|
12123
|
+
}
|
|
11826
12124
|
})
|
|
11827
12125
|
.next(() => {
|
|
11828
12126
|
// Finally, filter out any documents that don't actually match
|
|
@@ -11835,29 +12133,6 @@ class LocalDocumentsView {
|
|
|
11835
12133
|
return results;
|
|
11836
12134
|
});
|
|
11837
12135
|
}
|
|
11838
|
-
addMissingBaseDocuments(transaction, matchingMutationBatches, existingDocuments) {
|
|
11839
|
-
let missingBaseDocEntriesForPatching = documentKeySet();
|
|
11840
|
-
for (const batch of matchingMutationBatches) {
|
|
11841
|
-
for (const mutation of batch.mutations) {
|
|
11842
|
-
if (mutation instanceof PatchMutation &&
|
|
11843
|
-
existingDocuments.get(mutation.key) === null) {
|
|
11844
|
-
missingBaseDocEntriesForPatching =
|
|
11845
|
-
missingBaseDocEntriesForPatching.add(mutation.key);
|
|
11846
|
-
}
|
|
11847
|
-
}
|
|
11848
|
-
}
|
|
11849
|
-
let mergedDocuments = existingDocuments;
|
|
11850
|
-
return this.remoteDocumentCache
|
|
11851
|
-
.getEntries(transaction, missingBaseDocEntriesForPatching)
|
|
11852
|
-
.next(missingBaseDocs => {
|
|
11853
|
-
missingBaseDocs.forEach((key, doc) => {
|
|
11854
|
-
if (doc.isFoundDocument()) {
|
|
11855
|
-
mergedDocuments = mergedDocuments.insert(key, doc);
|
|
11856
|
-
}
|
|
11857
|
-
});
|
|
11858
|
-
return mergedDocuments;
|
|
11859
|
-
});
|
|
11860
|
-
}
|
|
11861
12136
|
}
|
|
11862
12137
|
|
|
11863
12138
|
/**
|
|
@@ -11916,11 +12191,18 @@ class LocalStoreImpl {
|
|
|
11916
12191
|
* PORTING NOTE: This is only used for multi-tab synchronization.
|
|
11917
12192
|
*/
|
|
11918
12193
|
this.lastDocumentChangeReadTime = SnapshotVersion.min();
|
|
11919
|
-
this.mutationQueue = persistence.getMutationQueue(initialUser);
|
|
11920
12194
|
this.remoteDocuments = persistence.getRemoteDocumentCache();
|
|
11921
12195
|
this.targetCache = persistence.getTargetCache();
|
|
11922
|
-
this.localDocuments = new LocalDocumentsView(this.remoteDocuments, this.mutationQueue, this.persistence.getIndexManager());
|
|
11923
12196
|
this.bundleCache = persistence.getBundleCache();
|
|
12197
|
+
this.initializeUserComponents(initialUser);
|
|
12198
|
+
}
|
|
12199
|
+
initializeUserComponents(user) {
|
|
12200
|
+
// TODO(indexing): Add spec tests that test these components change after a
|
|
12201
|
+
// user change
|
|
12202
|
+
this.indexManager = this.persistence.getIndexManager(user);
|
|
12203
|
+
this.mutationQueue = this.persistence.getMutationQueue(user, this.indexManager);
|
|
12204
|
+
this.localDocuments = new LocalDocumentsView(this.remoteDocuments, this.mutationQueue, this.indexManager);
|
|
12205
|
+
this.remoteDocuments.setIndexManager(this.indexManager);
|
|
11924
12206
|
this.queryEngine.setLocalDocumentsView(this.localDocuments);
|
|
11925
12207
|
}
|
|
11926
12208
|
collectGarbage(garbageCollector) {
|
|
@@ -11942,8 +12224,6 @@ persistence, queryEngine, initialUser, serializer) {
|
|
|
11942
12224
|
// change.
|
|
11943
12225
|
async function localStoreHandleUserChange(localStore, user) {
|
|
11944
12226
|
const localStoreImpl = debugCast(localStore);
|
|
11945
|
-
let newMutationQueue = localStoreImpl.mutationQueue;
|
|
11946
|
-
let newLocalDocuments = localStoreImpl.localDocuments;
|
|
11947
12227
|
const result = await localStoreImpl.persistence.runTransaction('Handle user change', 'readonly', txn => {
|
|
11948
12228
|
// Swap out the mutation queue, grabbing the pending mutation batches
|
|
11949
12229
|
// before and after.
|
|
@@ -11952,11 +12232,8 @@ async function localStoreHandleUserChange(localStore, user) {
|
|
|
11952
12232
|
.getAllMutationBatches(txn)
|
|
11953
12233
|
.next(promisedOldBatches => {
|
|
11954
12234
|
oldBatches = promisedOldBatches;
|
|
11955
|
-
|
|
11956
|
-
|
|
11957
|
-
// MutationQueue.
|
|
11958
|
-
newLocalDocuments = new LocalDocumentsView(localStoreImpl.remoteDocuments, newMutationQueue, localStoreImpl.persistence.getIndexManager());
|
|
11959
|
-
return newMutationQueue.getAllMutationBatches(txn);
|
|
12235
|
+
localStoreImpl.initializeUserComponents(user);
|
|
12236
|
+
return localStoreImpl.mutationQueue.getAllMutationBatches(txn);
|
|
11960
12237
|
})
|
|
11961
12238
|
.next(newBatches => {
|
|
11962
12239
|
const removedBatchIds = [];
|
|
@@ -11977,7 +12254,7 @@ async function localStoreHandleUserChange(localStore, user) {
|
|
|
11977
12254
|
}
|
|
11978
12255
|
// Return the set of all (potentially) changed documents and the list
|
|
11979
12256
|
// of mutation batch IDs that were affected by change.
|
|
11980
|
-
return
|
|
12257
|
+
return localStoreImpl.localDocuments
|
|
11981
12258
|
.getDocuments(txn, changedKeys)
|
|
11982
12259
|
.next(affectedDocuments => {
|
|
11983
12260
|
return {
|
|
@@ -11988,9 +12265,6 @@ async function localStoreHandleUserChange(localStore, user) {
|
|
|
11988
12265
|
});
|
|
11989
12266
|
});
|
|
11990
12267
|
});
|
|
11991
|
-
localStoreImpl.mutationQueue = newMutationQueue;
|
|
11992
|
-
localStoreImpl.localDocuments = newLocalDocuments;
|
|
11993
|
-
localStoreImpl.queryEngine.setLocalDocumentsView(localStoreImpl.localDocuments);
|
|
11994
12268
|
return result;
|
|
11995
12269
|
}
|
|
11996
12270
|
/* Accepts locally generated Mutations and commit them to storage. */
|
|
@@ -13056,14 +13330,16 @@ class MemoryRemoteDocumentCacheImpl {
|
|
|
13056
13330
|
* expected to just return 0 to avoid unnecessarily doing the work of
|
|
13057
13331
|
* calculating the size.
|
|
13058
13332
|
*/
|
|
13059
|
-
constructor(
|
|
13060
|
-
this.indexManager = indexManager;
|
|
13333
|
+
constructor(sizer) {
|
|
13061
13334
|
this.sizer = sizer;
|
|
13062
13335
|
/** Underlying cache of documents and their read times. */
|
|
13063
13336
|
this.docs = documentEntryMap();
|
|
13064
13337
|
/** Size of all cached documents. */
|
|
13065
13338
|
this.size = 0;
|
|
13066
13339
|
}
|
|
13340
|
+
setIndexManager(indexManager) {
|
|
13341
|
+
this.indexManager = indexManager;
|
|
13342
|
+
}
|
|
13067
13343
|
/**
|
|
13068
13344
|
* Adds the supplied entry to the cache and updates the cache size as appropriate.
|
|
13069
13345
|
*
|
|
@@ -13111,21 +13387,22 @@ class MemoryRemoteDocumentCacheImpl {
|
|
|
13111
13387
|
});
|
|
13112
13388
|
return PersistencePromise.resolve(results);
|
|
13113
13389
|
}
|
|
13114
|
-
|
|
13390
|
+
getAll(transaction, collectionPath, sinceReadTime) {
|
|
13115
13391
|
let results = mutableDocumentMap();
|
|
13116
13392
|
// Documents are ordered by key, so we can use a prefix scan to narrow down
|
|
13117
13393
|
// the documents we need to match the query against.
|
|
13118
|
-
const prefix = new DocumentKey(
|
|
13394
|
+
const prefix = new DocumentKey(collectionPath.child(''));
|
|
13119
13395
|
const iterator = this.docs.getIteratorFrom(prefix);
|
|
13120
13396
|
while (iterator.hasNext()) {
|
|
13121
13397
|
const { key, value: { document } } = iterator.getNext();
|
|
13122
|
-
if (!
|
|
13398
|
+
if (!collectionPath.isPrefixOf(key.path)) {
|
|
13123
13399
|
break;
|
|
13124
13400
|
}
|
|
13125
|
-
if (
|
|
13401
|
+
if (key.path.length > collectionPath.length + 1) {
|
|
13402
|
+
// Exclude entries from subcollections.
|
|
13126
13403
|
continue;
|
|
13127
13404
|
}
|
|
13128
|
-
if (
|
|
13405
|
+
if (document.readTime.compareTo(sinceReadTime) <= 0) {
|
|
13129
13406
|
continue;
|
|
13130
13407
|
}
|
|
13131
13408
|
results = results.insert(document.key, document.mutableCopy());
|
|
@@ -13147,13 +13424,12 @@ class MemoryRemoteDocumentCacheImpl {
|
|
|
13147
13424
|
/**
|
|
13148
13425
|
* Creates a new memory-only RemoteDocumentCache.
|
|
13149
13426
|
*
|
|
13150
|
-
* @param indexManager - A class that manages collection group indices.
|
|
13151
13427
|
* @param sizer - Used to assess the size of a document. For eager GC, this is
|
|
13152
13428
|
* expected to just return 0 to avoid unnecessarily doing the work of
|
|
13153
13429
|
* calculating the size.
|
|
13154
13430
|
*/
|
|
13155
|
-
function newMemoryRemoteDocumentCache(
|
|
13156
|
-
return new MemoryRemoteDocumentCacheImpl(
|
|
13431
|
+
function newMemoryRemoteDocumentCache(sizer) {
|
|
13432
|
+
return new MemoryRemoteDocumentCacheImpl(sizer);
|
|
13157
13433
|
}
|
|
13158
13434
|
/**
|
|
13159
13435
|
* Handles the details of adding and updating documents in the MemoryRemoteDocumentCache.
|
|
@@ -13354,7 +13630,7 @@ class MemoryPersistence {
|
|
|
13354
13630
|
this.targetCache = new MemoryTargetCache(this);
|
|
13355
13631
|
const sizer = (doc) => this.referenceDelegate.documentSize(doc);
|
|
13356
13632
|
this.indexManager = new MemoryIndexManager();
|
|
13357
|
-
this.remoteDocumentCache = newMemoryRemoteDocumentCache(
|
|
13633
|
+
this.remoteDocumentCache = newMemoryRemoteDocumentCache(sizer);
|
|
13358
13634
|
this.serializer = new LocalSerializer(serializer);
|
|
13359
13635
|
this.bundleCache = new MemoryBundleCache(this.serializer);
|
|
13360
13636
|
}
|
|
@@ -13375,13 +13651,15 @@ class MemoryPersistence {
|
|
|
13375
13651
|
setNetworkEnabled() {
|
|
13376
13652
|
// No op.
|
|
13377
13653
|
}
|
|
13378
|
-
getIndexManager() {
|
|
13654
|
+
getIndexManager(user) {
|
|
13655
|
+
// We do not currently support indices for memory persistence, so we can
|
|
13656
|
+
// return the same shared instance of the memory index manager.
|
|
13379
13657
|
return this.indexManager;
|
|
13380
13658
|
}
|
|
13381
|
-
getMutationQueue(user) {
|
|
13659
|
+
getMutationQueue(user, indexManager) {
|
|
13382
13660
|
let queue = this.mutationQueues[user.toKey()];
|
|
13383
13661
|
if (!queue) {
|
|
13384
|
-
queue = new MemoryMutationQueue(
|
|
13662
|
+
queue = new MemoryMutationQueue(indexManager, this.referenceDelegate);
|
|
13385
13663
|
this.mutationQueues[user.toKey()] = queue;
|
|
13386
13664
|
}
|
|
13387
13665
|
return queue;
|
|
@@ -20344,12 +20622,12 @@ async function syncEngineListen(syncEngine, query) {
|
|
|
20344
20622
|
}
|
|
20345
20623
|
else {
|
|
20346
20624
|
const targetData = await localStoreAllocateTarget(syncEngineImpl.localStore, queryToTarget(query));
|
|
20347
|
-
const status = syncEngineImpl.sharedClientState.addLocalQueryTarget(targetData.targetId);
|
|
20348
|
-
targetId = targetData.targetId;
|
|
20349
|
-
viewSnapshot = await initializeViewAndComputeSnapshot(syncEngineImpl, query, targetId, status === 'current');
|
|
20350
20625
|
if (syncEngineImpl.isPrimaryClient) {
|
|
20351
20626
|
remoteStoreListen(syncEngineImpl.remoteStore, targetData);
|
|
20352
20627
|
}
|
|
20628
|
+
const status = syncEngineImpl.sharedClientState.addLocalQueryTarget(targetData.targetId);
|
|
20629
|
+
targetId = targetData.targetId;
|
|
20630
|
+
viewSnapshot = await initializeViewAndComputeSnapshot(syncEngineImpl, query, targetId, status === 'current');
|
|
20353
20631
|
}
|
|
20354
20632
|
return viewSnapshot;
|
|
20355
20633
|
}
|
|
@@ -24857,8 +25135,7 @@ class DocumentSnapshot extends DocumentSnapshot$1 {
|
|
|
24857
25135
|
this.metadata = metadata;
|
|
24858
25136
|
}
|
|
24859
25137
|
/**
|
|
24860
|
-
*
|
|
24861
|
-
* exists. True if the document exists.
|
|
25138
|
+
* Returns whether or not the data exists. True if the document exists.
|
|
24862
25139
|
*/
|
|
24863
25140
|
exists() {
|
|
24864
25141
|
return super.exists();
|
|
@@ -25232,51 +25509,53 @@ function limitToLast(limit) {
|
|
|
25232
25509
|
return new QueryLimitConstraint('limitToLast', limit, "L" /* Last */);
|
|
25233
25510
|
}
|
|
25234
25511
|
class QueryStartAtConstraint extends QueryConstraint {
|
|
25235
|
-
constructor(type, _docOrFields,
|
|
25512
|
+
constructor(type, _docOrFields, _inclusive) {
|
|
25236
25513
|
super();
|
|
25237
25514
|
this.type = type;
|
|
25238
25515
|
this._docOrFields = _docOrFields;
|
|
25239
|
-
this.
|
|
25516
|
+
this._inclusive = _inclusive;
|
|
25240
25517
|
}
|
|
25241
25518
|
_apply(query) {
|
|
25242
|
-
const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this.
|
|
25519
|
+
const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._inclusive);
|
|
25243
25520
|
return new Query(query.firestore, query.converter, queryWithStartAt(query._query, bound));
|
|
25244
25521
|
}
|
|
25245
25522
|
}
|
|
25246
25523
|
function startAt(...docOrFields) {
|
|
25247
|
-
return new QueryStartAtConstraint('startAt', docOrFields,
|
|
25524
|
+
return new QueryStartAtConstraint('startAt', docOrFields,
|
|
25525
|
+
/*inclusive=*/ true);
|
|
25248
25526
|
}
|
|
25249
25527
|
function startAfter(...docOrFields) {
|
|
25250
25528
|
return new QueryStartAtConstraint('startAfter', docOrFields,
|
|
25251
|
-
/*
|
|
25529
|
+
/*inclusive=*/ false);
|
|
25252
25530
|
}
|
|
25253
25531
|
class QueryEndAtConstraint extends QueryConstraint {
|
|
25254
|
-
constructor(type, _docOrFields,
|
|
25532
|
+
constructor(type, _docOrFields, _inclusive) {
|
|
25255
25533
|
super();
|
|
25256
25534
|
this.type = type;
|
|
25257
25535
|
this._docOrFields = _docOrFields;
|
|
25258
|
-
this.
|
|
25536
|
+
this._inclusive = _inclusive;
|
|
25259
25537
|
}
|
|
25260
25538
|
_apply(query) {
|
|
25261
|
-
const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this.
|
|
25539
|
+
const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._inclusive);
|
|
25262
25540
|
return new Query(query.firestore, query.converter, queryWithEndAt(query._query, bound));
|
|
25263
25541
|
}
|
|
25264
25542
|
}
|
|
25265
25543
|
function endBefore(...docOrFields) {
|
|
25266
|
-
return new QueryEndAtConstraint('endBefore', docOrFields,
|
|
25544
|
+
return new QueryEndAtConstraint('endBefore', docOrFields,
|
|
25545
|
+
/*inclusive=*/ false);
|
|
25267
25546
|
}
|
|
25268
25547
|
function endAt(...docOrFields) {
|
|
25269
|
-
return new QueryEndAtConstraint('endAt', docOrFields, /*
|
|
25548
|
+
return new QueryEndAtConstraint('endAt', docOrFields, /*inclusive=*/ true);
|
|
25270
25549
|
}
|
|
25271
25550
|
/** Helper function to create a bound from a document or fields */
|
|
25272
|
-
function newQueryBoundFromDocOrFields(query, methodName, docOrFields,
|
|
25551
|
+
function newQueryBoundFromDocOrFields(query, methodName, docOrFields, inclusive) {
|
|
25273
25552
|
docOrFields[0] = util$1.getModularInstance(docOrFields[0]);
|
|
25274
25553
|
if (docOrFields[0] instanceof DocumentSnapshot$1) {
|
|
25275
|
-
return newQueryBoundFromDocument(query._query, query.firestore._databaseId, methodName, docOrFields[0]._document,
|
|
25554
|
+
return newQueryBoundFromDocument(query._query, query.firestore._databaseId, methodName, docOrFields[0]._document, inclusive);
|
|
25276
25555
|
}
|
|
25277
25556
|
else {
|
|
25278
25557
|
const reader = newUserDataReader(query.firestore);
|
|
25279
|
-
return newQueryBoundFromFields(query._query, query.firestore._databaseId, reader, methodName, docOrFields,
|
|
25558
|
+
return newQueryBoundFromFields(query._query, query.firestore._databaseId, reader, methodName, docOrFields, inclusive);
|
|
25280
25559
|
}
|
|
25281
25560
|
}
|
|
25282
25561
|
function newQueryFilter(query, methodName, dataReader, databaseId, fieldPath, op, value) {
|
|
@@ -25334,7 +25613,7 @@ function newQueryOrderBy(query, fieldPath, direction) {
|
|
|
25334
25613
|
* of the query or if any of the fields in the order by are an uncommitted
|
|
25335
25614
|
* server timestamp.
|
|
25336
25615
|
*/
|
|
25337
|
-
function newQueryBoundFromDocument(query, databaseId, methodName, doc,
|
|
25616
|
+
function newQueryBoundFromDocument(query, databaseId, methodName, doc, inclusive) {
|
|
25338
25617
|
if (!doc) {
|
|
25339
25618
|
throw new FirestoreError(Code.NOT_FOUND, `Can't use a DocumentSnapshot that doesn't exist for ` +
|
|
25340
25619
|
`${methodName}().`);
|
|
@@ -25371,12 +25650,12 @@ function newQueryBoundFromDocument(query, databaseId, methodName, doc, before) {
|
|
|
25371
25650
|
}
|
|
25372
25651
|
}
|
|
25373
25652
|
}
|
|
25374
|
-
return new Bound(components,
|
|
25653
|
+
return new Bound(components, inclusive);
|
|
25375
25654
|
}
|
|
25376
25655
|
/**
|
|
25377
25656
|
* Converts a list of field values to a `Bound` for the given query.
|
|
25378
25657
|
*/
|
|
25379
|
-
function newQueryBoundFromFields(query, databaseId, dataReader, methodName, values,
|
|
25658
|
+
function newQueryBoundFromFields(query, databaseId, dataReader, methodName, values, inclusive) {
|
|
25380
25659
|
// Use explicit order by's because it has to match the query the user made
|
|
25381
25660
|
const orderBy = query.explicitOrderBy;
|
|
25382
25661
|
if (values.length > orderBy.length) {
|
|
@@ -25413,7 +25692,7 @@ function newQueryBoundFromFields(query, databaseId, dataReader, methodName, valu
|
|
|
25413
25692
|
components.push(wrapped);
|
|
25414
25693
|
}
|
|
25415
25694
|
}
|
|
25416
|
-
return new Bound(components,
|
|
25695
|
+
return new Bound(components, inclusive);
|
|
25417
25696
|
}
|
|
25418
25697
|
/**
|
|
25419
25698
|
* Parses the given `documentIdValue` into a `ReferenceValue`, throwing
|