@firebase/firestore 3.4.4-canary.4cec42313 → 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 +35 -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 +2967 -2808
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm5.js +2870 -2698
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +397 -203
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/index.node.mjs +397 -203
- package/dist/index.node.mjs.map +1 -1
- package/dist/index.rn.js +3215 -3060
- 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 +35 -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 +35 -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 +143 -143
- 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 +35 -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
|
|
@@ -1778,7 +1778,10 @@ DbNamedQuery.keyPath = 'name';
|
|
|
1778
1778
|
/** An object representing the global configuration for a field index. */
|
|
1779
1779
|
class DbIndexConfiguration {
|
|
1780
1780
|
constructor(
|
|
1781
|
-
/**
|
|
1781
|
+
/**
|
|
1782
|
+
* The index id for this entry. Undefined for indexes that are not yet
|
|
1783
|
+
* persisted.
|
|
1784
|
+
*/
|
|
1782
1785
|
indexId,
|
|
1783
1786
|
/** The collection group this index belongs to. */
|
|
1784
1787
|
collectionGroup,
|
|
@@ -1792,6 +1795,16 @@ class DbIndexConfiguration {
|
|
|
1792
1795
|
/** Name of the IndexedDb object store. */
|
|
1793
1796
|
DbIndexConfiguration.store = 'indexConfiguration';
|
|
1794
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';
|
|
1795
1808
|
/**
|
|
1796
1809
|
* An object describing how up-to-date the index backfill is for each user and
|
|
1797
1810
|
* index.
|
|
@@ -1833,8 +1846,18 @@ class DbIndexState {
|
|
|
1833
1846
|
/** Name of the IndexedDb object store. */
|
|
1834
1847
|
DbIndexState.store = 'indexState';
|
|
1835
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'];
|
|
1836
1859
|
/** An object that stores the encoded entries for all documents and fields. */
|
|
1837
|
-
class
|
|
1860
|
+
class DbIndexEntry {
|
|
1838
1861
|
constructor(
|
|
1839
1862
|
/** The index id for this entry. */
|
|
1840
1863
|
indexId,
|
|
@@ -1854,8 +1877,8 @@ class DbIndexEntries {
|
|
|
1854
1877
|
}
|
|
1855
1878
|
}
|
|
1856
1879
|
/** Name of the IndexedDb object store. */
|
|
1857
|
-
|
|
1858
|
-
|
|
1880
|
+
DbIndexEntry.store = 'indexEntries';
|
|
1881
|
+
DbIndexEntry.keyPath = [
|
|
1859
1882
|
'indexId',
|
|
1860
1883
|
'uid',
|
|
1861
1884
|
'arrayValue',
|
|
@@ -1885,18 +1908,24 @@ const V8_STORES = [...V6_STORES, DbCollectionParent.store];
|
|
|
1885
1908
|
// V9 does not change the set of stores.
|
|
1886
1909
|
// V10 does not change the set of stores.
|
|
1887
1910
|
const V11_STORES = [...V8_STORES, DbBundle.store, DbNamedQuery.store];
|
|
1888
|
-
[
|
|
1911
|
+
const V12_STORES = [
|
|
1889
1912
|
...V11_STORES,
|
|
1890
1913
|
DbIndexConfiguration.store,
|
|
1891
1914
|
DbIndexState.store,
|
|
1892
|
-
|
|
1915
|
+
DbIndexEntry.store
|
|
1893
1916
|
];
|
|
1894
|
-
/**
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
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
|
+
}
|
|
1900
1929
|
|
|
1901
1930
|
/**
|
|
1902
1931
|
* @license
|
|
@@ -2193,6 +2222,15 @@ class SimpleDbTransaction {
|
|
|
2193
2222
|
this.transaction.abort();
|
|
2194
2223
|
}
|
|
2195
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
|
+
}
|
|
2196
2234
|
/**
|
|
2197
2235
|
* Returns a SimpleDbStore<KeyType, ValueType> for the specified store. All
|
|
2198
2236
|
* operations performed on the SimpleDbStore happen within the context of this
|
|
@@ -2389,6 +2427,10 @@ class SimpleDb {
|
|
|
2389
2427
|
this.db = await this.ensureDb(action);
|
|
2390
2428
|
const transaction = SimpleDbTransaction.open(this.db, action, readonly ? 'readonly' : 'readwrite', objectStores);
|
|
2391
2429
|
const transactionFnResult = transactionFn(transaction)
|
|
2430
|
+
.next(result => {
|
|
2431
|
+
transaction.maybeCommit();
|
|
2432
|
+
return result;
|
|
2433
|
+
})
|
|
2392
2434
|
.catch(error => {
|
|
2393
2435
|
// Abort the transaction if there was an error.
|
|
2394
2436
|
transaction.abort(error);
|
|
@@ -2561,13 +2603,29 @@ class SimpleDbStore {
|
|
|
2561
2603
|
return wrapRequest(request);
|
|
2562
2604
|
}
|
|
2563
2605
|
loadAll(indexOrRange, range) {
|
|
2564
|
-
const
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
return
|
|
2570
|
-
|
|
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
|
+
}
|
|
2571
2629
|
}
|
|
2572
2630
|
deleteAll(indexOrRange, range) {
|
|
2573
2631
|
logDebug(LOG_TAG$g, 'DELETE ALL', this.store.name);
|
|
@@ -4421,12 +4479,12 @@ class FieldIndex {
|
|
|
4421
4479
|
/** The collection ID this index applies to. */
|
|
4422
4480
|
collectionGroup,
|
|
4423
4481
|
/** The field segments for this index. */
|
|
4424
|
-
|
|
4482
|
+
fields,
|
|
4425
4483
|
/** Shows how up-to-date the index is for the current user. */
|
|
4426
4484
|
indexState) {
|
|
4427
4485
|
this.indexId = indexId;
|
|
4428
4486
|
this.collectionGroup = collectionGroup;
|
|
4429
|
-
this.
|
|
4487
|
+
this.fields = fields;
|
|
4430
4488
|
this.indexState = indexState;
|
|
4431
4489
|
}
|
|
4432
4490
|
}
|
|
@@ -4536,27 +4594,29 @@ function newTarget(path, collectionGroup = null, orderBy = [], filters = [], lim
|
|
|
4536
4594
|
function canonifyTarget(target) {
|
|
4537
4595
|
const targetImpl = debugCast(target);
|
|
4538
4596
|
if (targetImpl.memoizedCanonicalId === null) {
|
|
4539
|
-
let
|
|
4597
|
+
let str = targetImpl.path.canonicalString();
|
|
4540
4598
|
if (targetImpl.collectionGroup !== null) {
|
|
4541
|
-
|
|
4599
|
+
str += '|cg:' + targetImpl.collectionGroup;
|
|
4542
4600
|
}
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4601
|
+
str += '|f:';
|
|
4602
|
+
str += targetImpl.filters.map(f => canonifyFilter(f)).join(',');
|
|
4603
|
+
str += '|ob:';
|
|
4604
|
+
str += targetImpl.orderBy.map(o => canonifyOrderBy(o)).join(',');
|
|
4547
4605
|
if (!isNullOrUndefined(targetImpl.limit)) {
|
|
4548
|
-
|
|
4549
|
-
|
|
4606
|
+
str += '|l:';
|
|
4607
|
+
str += targetImpl.limit;
|
|
4550
4608
|
}
|
|
4551
4609
|
if (targetImpl.startAt) {
|
|
4552
|
-
|
|
4553
|
-
|
|
4610
|
+
str += '|lb:';
|
|
4611
|
+
str += targetImpl.startAt.inclusive ? 'b:' : 'a:';
|
|
4612
|
+
str += targetImpl.startAt.position.map(p => canonicalId(p)).join(',');
|
|
4554
4613
|
}
|
|
4555
4614
|
if (targetImpl.endAt) {
|
|
4556
|
-
|
|
4557
|
-
|
|
4615
|
+
str += '|ub:';
|
|
4616
|
+
str += targetImpl.endAt.inclusive ? 'a:' : 'b:';
|
|
4617
|
+
str += targetImpl.endAt.position.map(p => canonicalId(p)).join(',');
|
|
4558
4618
|
}
|
|
4559
|
-
targetImpl.memoizedCanonicalId =
|
|
4619
|
+
targetImpl.memoizedCanonicalId = str;
|
|
4560
4620
|
}
|
|
4561
4621
|
return targetImpl.memoizedCanonicalId;
|
|
4562
4622
|
}
|
|
@@ -4579,10 +4639,14 @@ function stringifyTarget(target) {
|
|
|
4579
4639
|
.join(', ')}]`;
|
|
4580
4640
|
}
|
|
4581
4641
|
if (target.startAt) {
|
|
4582
|
-
str += ', startAt: '
|
|
4642
|
+
str += ', startAt: ';
|
|
4643
|
+
str += target.startAt.inclusive ? 'b:' : 'a:';
|
|
4644
|
+
str += target.startAt.position.map(p => canonicalId(p)).join(',');
|
|
4583
4645
|
}
|
|
4584
4646
|
if (target.endAt) {
|
|
4585
|
-
str += ', endAt: '
|
|
4647
|
+
str += ', endAt: ';
|
|
4648
|
+
str += target.endAt.inclusive ? 'a:' : 'b:';
|
|
4649
|
+
str += target.endAt.position.map(p => canonicalId(p)).join(',');
|
|
4586
4650
|
}
|
|
4587
4651
|
return `Target(${str})`;
|
|
4588
4652
|
}
|
|
@@ -4805,7 +4869,6 @@ class ArrayContainsAnyFilter extends FieldFilter {
|
|
|
4805
4869
|
return other.arrayValue.values.some(val => arrayValueContains(this.value.arrayValue, val));
|
|
4806
4870
|
}
|
|
4807
4871
|
}
|
|
4808
|
-
// TODO(indexing): Change Bound.before to "inclusive"
|
|
4809
4872
|
/**
|
|
4810
4873
|
* Represents a bound of a query.
|
|
4811
4874
|
*
|
|
@@ -4821,17 +4884,11 @@ class ArrayContainsAnyFilter extends FieldFilter {
|
|
|
4821
4884
|
* just after the provided values.
|
|
4822
4885
|
*/
|
|
4823
4886
|
class Bound {
|
|
4824
|
-
constructor(position,
|
|
4887
|
+
constructor(position, inclusive) {
|
|
4825
4888
|
this.position = position;
|
|
4826
|
-
this.
|
|
4889
|
+
this.inclusive = inclusive;
|
|
4827
4890
|
}
|
|
4828
4891
|
}
|
|
4829
|
-
function canonifyBound(bound) {
|
|
4830
|
-
// TODO(b/29183165): Make this collision robust.
|
|
4831
|
-
return `${bound.before ? 'b' : 'a'}:${bound.position
|
|
4832
|
-
.map(p => canonicalId(p))
|
|
4833
|
-
.join(',')}`;
|
|
4834
|
-
}
|
|
4835
4892
|
/**
|
|
4836
4893
|
* An ordering on a field, in some Direction. Direction defaults to ASCENDING.
|
|
4837
4894
|
*/
|
|
@@ -4851,11 +4908,7 @@ function stringifyOrderBy(orderBy) {
|
|
|
4851
4908
|
function orderByEquals(left, right) {
|
|
4852
4909
|
return left.dir === right.dir && left.field.isEqual(right.field);
|
|
4853
4910
|
}
|
|
4854
|
-
|
|
4855
|
-
* Returns true if a document sorts before a bound using the provided sort
|
|
4856
|
-
* order.
|
|
4857
|
-
*/
|
|
4858
|
-
function sortsBeforeDocument(bound, orderBy, doc) {
|
|
4911
|
+
function boundCompareToDocument(bound, orderBy, doc) {
|
|
4859
4912
|
let comparison = 0;
|
|
4860
4913
|
for (let i = 0; i < bound.position.length; i++) {
|
|
4861
4914
|
const orderByComponent = orderBy[i];
|
|
@@ -4874,7 +4927,23 @@ function sortsBeforeDocument(bound, orderBy, doc) {
|
|
|
4874
4927
|
break;
|
|
4875
4928
|
}
|
|
4876
4929
|
}
|
|
4877
|
-
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;
|
|
4878
4947
|
}
|
|
4879
4948
|
function boundEquals(left, right) {
|
|
4880
4949
|
if (left === null) {
|
|
@@ -4883,7 +4952,7 @@ function boundEquals(left, right) {
|
|
|
4883
4952
|
else if (right === null) {
|
|
4884
4953
|
return false;
|
|
4885
4954
|
}
|
|
4886
|
-
if (left.
|
|
4955
|
+
if (left.inclusive !== right.inclusive ||
|
|
4887
4956
|
left.position.length !== right.position.length) {
|
|
4888
4957
|
return false;
|
|
4889
4958
|
}
|
|
@@ -5087,10 +5156,10 @@ function queryToTarget(query) {
|
|
|
5087
5156
|
}
|
|
5088
5157
|
// We need to swap the cursors to match the now-flipped query ordering.
|
|
5089
5158
|
const startAt = queryImpl.endAt
|
|
5090
|
-
? new Bound(queryImpl.endAt.position, !queryImpl.endAt.
|
|
5159
|
+
? new Bound(queryImpl.endAt.position, !queryImpl.endAt.inclusive)
|
|
5091
5160
|
: null;
|
|
5092
5161
|
const endAt = queryImpl.startAt
|
|
5093
|
-
? new Bound(queryImpl.startAt.position, !queryImpl.startAt.
|
|
5162
|
+
? new Bound(queryImpl.startAt.position, !queryImpl.startAt.inclusive)
|
|
5094
5163
|
: null;
|
|
5095
5164
|
// Now return as a LimitType.First query.
|
|
5096
5165
|
queryImpl.memoizedTarget = newTarget(queryImpl.path, queryImpl.collectionGroup, orderBys, queryImpl.filters, queryImpl.limit, startAt, endAt);
|
|
@@ -5178,11 +5247,11 @@ function queryMatchesFilters(query, doc) {
|
|
|
5178
5247
|
/** Makes sure a document is within the bounds, if provided. */
|
|
5179
5248
|
function queryMatchesBounds(query, doc) {
|
|
5180
5249
|
if (query.startAt &&
|
|
5181
|
-
!
|
|
5250
|
+
!boundSortsBeforeDocument(query.startAt, queryOrderBy(query), doc)) {
|
|
5182
5251
|
return false;
|
|
5183
5252
|
}
|
|
5184
5253
|
if (query.endAt &&
|
|
5185
|
-
|
|
5254
|
+
!boundSortsAfterDocument(query.endAt, queryOrderBy(query), doc)) {
|
|
5186
5255
|
return false;
|
|
5187
5256
|
}
|
|
5188
5257
|
return true;
|
|
@@ -8061,10 +8130,10 @@ function toQueryTarget(serializer, target) {
|
|
|
8061
8130
|
result.structuredQuery.limit = limit;
|
|
8062
8131
|
}
|
|
8063
8132
|
if (target.startAt) {
|
|
8064
|
-
result.structuredQuery.startAt =
|
|
8133
|
+
result.structuredQuery.startAt = toStartAtCursor(target.startAt);
|
|
8065
8134
|
}
|
|
8066
8135
|
if (target.endAt) {
|
|
8067
|
-
result.structuredQuery.endAt =
|
|
8136
|
+
result.structuredQuery.endAt = toEndAtCursor(target.endAt);
|
|
8068
8137
|
}
|
|
8069
8138
|
return result;
|
|
8070
8139
|
}
|
|
@@ -8097,11 +8166,11 @@ function convertQueryTargetToQuery(target) {
|
|
|
8097
8166
|
}
|
|
8098
8167
|
let startAt = null;
|
|
8099
8168
|
if (query.startAt) {
|
|
8100
|
-
startAt =
|
|
8169
|
+
startAt = fromStartAtCursor(query.startAt);
|
|
8101
8170
|
}
|
|
8102
8171
|
let endAt = null;
|
|
8103
8172
|
if (query.endAt) {
|
|
8104
|
-
endAt =
|
|
8173
|
+
endAt = fromEndAtCursor(query.endAt);
|
|
8105
8174
|
}
|
|
8106
8175
|
return newQuery(path, collectionGroup, orderBy, filterBy, limit, "F" /* First */, startAt, endAt);
|
|
8107
8176
|
}
|
|
@@ -8192,16 +8261,27 @@ function toOrder(orderBys) {
|
|
|
8192
8261
|
function fromOrder(orderBys) {
|
|
8193
8262
|
return orderBys.map(order => fromPropertyOrder(order));
|
|
8194
8263
|
}
|
|
8195
|
-
function
|
|
8264
|
+
function toStartAtCursor(cursor) {
|
|
8196
8265
|
return {
|
|
8197
|
-
before: cursor.
|
|
8266
|
+
before: cursor.inclusive,
|
|
8198
8267
|
values: cursor.position
|
|
8199
8268
|
};
|
|
8200
8269
|
}
|
|
8201
|
-
function
|
|
8202
|
-
|
|
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;
|
|
8203
8283
|
const position = cursor.values || [];
|
|
8204
|
-
return new Bound(position,
|
|
8284
|
+
return new Bound(position, inclusive);
|
|
8205
8285
|
}
|
|
8206
8286
|
// visible for testing
|
|
8207
8287
|
function toDirection(dir) {
|
|
@@ -8665,6 +8745,19 @@ function fromBundleMetadata(metadata) {
|
|
|
8665
8745
|
version: metadata.version,
|
|
8666
8746
|
createTime: fromVersion(metadata.createTime)
|
|
8667
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);
|
|
8668
8761
|
}
|
|
8669
8762
|
|
|
8670
8763
|
/**
|
|
@@ -8754,6 +8847,38 @@ class MemoryIndexManager {
|
|
|
8754
8847
|
getCollectionParents(transaction, collectionId) {
|
|
8755
8848
|
return PersistencePromise.resolve(this.collectionParentIndex.getEntries(collectionId));
|
|
8756
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
|
+
}
|
|
8757
8882
|
}
|
|
8758
8883
|
/**
|
|
8759
8884
|
* Internal implementation of the collection-parent index exposed by MemoryIndexManager.
|
|
@@ -8805,17 +8930,22 @@ class MemoryCollectionParentIndex {
|
|
|
8805
8930
|
*/
|
|
8806
8931
|
/**
|
|
8807
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.
|
|
8808
8936
|
*/
|
|
8809
8937
|
class IndexedDbIndexManager {
|
|
8810
|
-
constructor() {
|
|
8938
|
+
constructor(user) {
|
|
8939
|
+
this.user = user;
|
|
8811
8940
|
/**
|
|
8812
8941
|
* An in-memory copy of the index entries we've already written since the SDK
|
|
8813
8942
|
* launched. Used to avoid re-writing the same entry repeatedly.
|
|
8814
8943
|
*
|
|
8815
|
-
* This is *NOT* a complete cache of what's in persistence and so can never be
|
|
8816
|
-
* satisfy reads.
|
|
8944
|
+
* This is *NOT* a complete cache of what's in persistence and so can never be
|
|
8945
|
+
* used to satisfy reads.
|
|
8817
8946
|
*/
|
|
8818
8947
|
this.collectionParentsCache = new MemoryCollectionParentIndex();
|
|
8948
|
+
this.uid = user.uid || '';
|
|
8819
8949
|
}
|
|
8820
8950
|
/**
|
|
8821
8951
|
* Adds a new entry to the collection parent index.
|
|
@@ -8862,6 +8992,85 @@ class IndexedDbIndexManager {
|
|
|
8862
8992
|
return parentPaths;
|
|
8863
8993
|
});
|
|
8864
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
|
+
}
|
|
8865
9074
|
}
|
|
8866
9075
|
/**
|
|
8867
9076
|
* Helper to get a typed SimpleDbStore for the collectionParents
|
|
@@ -8869,6 +9078,24 @@ class IndexedDbIndexManager {
|
|
|
8869
9078
|
*/
|
|
8870
9079
|
function collectionParentsStore(txn) {
|
|
8871
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);
|
|
8872
9099
|
}
|
|
8873
9100
|
|
|
8874
9101
|
/**
|
|
@@ -10338,12 +10565,10 @@ class RemoteDocumentChangeBuffer {
|
|
|
10338
10565
|
* `newIndexedDbRemoteDocumentCache()`.
|
|
10339
10566
|
*/
|
|
10340
10567
|
class IndexedDbRemoteDocumentCacheImpl {
|
|
10341
|
-
|
|
10342
|
-
* @param serializer - The document serializer.
|
|
10343
|
-
* @param indexManager - The query indexes that need to be maintained.
|
|
10344
|
-
*/
|
|
10345
|
-
constructor(serializer, indexManager) {
|
|
10568
|
+
constructor(serializer) {
|
|
10346
10569
|
this.serializer = serializer;
|
|
10570
|
+
}
|
|
10571
|
+
setIndexManager(indexManager) {
|
|
10347
10572
|
this.indexManager = indexManager;
|
|
10348
10573
|
}
|
|
10349
10574
|
/**
|
|
@@ -10465,21 +10690,21 @@ class IndexedDbRemoteDocumentCacheImpl {
|
|
|
10465
10690
|
}
|
|
10466
10691
|
});
|
|
10467
10692
|
}
|
|
10468
|
-
|
|
10693
|
+
getAll(transaction, collection, sinceReadTime) {
|
|
10469
10694
|
let results = mutableDocumentMap();
|
|
10470
|
-
const immediateChildrenPathLength =
|
|
10695
|
+
const immediateChildrenPathLength = collection.length + 1;
|
|
10471
10696
|
const iterationOptions = {};
|
|
10472
10697
|
if (sinceReadTime.isEqual(SnapshotVersion.min())) {
|
|
10473
10698
|
// Documents are ordered by key, so we can use a prefix scan to narrow
|
|
10474
10699
|
// down the documents we need to match the query against.
|
|
10475
|
-
const startKey =
|
|
10700
|
+
const startKey = collection.toArray();
|
|
10476
10701
|
iterationOptions.range = IDBKeyRange.lowerBound(startKey);
|
|
10477
10702
|
}
|
|
10478
10703
|
else {
|
|
10479
10704
|
// Execute an index-free query and filter by read time. This is safe
|
|
10480
10705
|
// since all document changes to queries that have a
|
|
10481
10706
|
// lastLimboFreeSnapshotVersion (`sinceReadTime`) have a read time set.
|
|
10482
|
-
const collectionKey =
|
|
10707
|
+
const collectionKey = collection.toArray();
|
|
10483
10708
|
const readTimeKey = toDbTimestampKey(sinceReadTime);
|
|
10484
10709
|
iterationOptions.range = IDBKeyRange.lowerBound([collectionKey, readTimeKey],
|
|
10485
10710
|
/* open= */ true);
|
|
@@ -10496,12 +10721,12 @@ class IndexedDbRemoteDocumentCacheImpl {
|
|
|
10496
10721
|
return;
|
|
10497
10722
|
}
|
|
10498
10723
|
const document = this.maybeDecodeDocument(DocumentKey.fromSegments(key), dbRemoteDoc);
|
|
10499
|
-
if (
|
|
10500
|
-
control.done();
|
|
10501
|
-
}
|
|
10502
|
-
else if (queryMatches(query, document)) {
|
|
10724
|
+
if (collection.isPrefixOf(document.key.path)) {
|
|
10503
10725
|
results = results.insert(document.key, document);
|
|
10504
10726
|
}
|
|
10727
|
+
else {
|
|
10728
|
+
control.done();
|
|
10729
|
+
}
|
|
10505
10730
|
})
|
|
10506
10731
|
.next(() => results);
|
|
10507
10732
|
}
|
|
@@ -10539,14 +10764,9 @@ class IndexedDbRemoteDocumentCacheImpl {
|
|
|
10539
10764
|
return MutableDocument.newInvalidDocument(documentKey);
|
|
10540
10765
|
}
|
|
10541
10766
|
}
|
|
10542
|
-
/**
|
|
10543
|
-
|
|
10544
|
-
|
|
10545
|
-
* @param serializer - The document serializer.
|
|
10546
|
-
* @param indexManager - The query indexes that need to be maintained.
|
|
10547
|
-
*/
|
|
10548
|
-
function newIndexedDbRemoteDocumentCache(serializer, indexManager) {
|
|
10549
|
-
return new IndexedDbRemoteDocumentCacheImpl(serializer, indexManager);
|
|
10767
|
+
/** Creates a new IndexedDbRemoteDocumentCache. */
|
|
10768
|
+
function newIndexedDbRemoteDocumentCache(serializer) {
|
|
10769
|
+
return new IndexedDbRemoteDocumentCacheImpl(serializer);
|
|
10550
10770
|
}
|
|
10551
10771
|
/**
|
|
10552
10772
|
* Returns the set of documents that have changed since the specified read
|
|
@@ -10992,14 +11212,17 @@ function createNamedQueriesStore(db) {
|
|
|
10992
11212
|
});
|
|
10993
11213
|
}
|
|
10994
11214
|
function createFieldIndex(db) {
|
|
10995
|
-
db.createObjectStore(DbIndexConfiguration.store, {
|
|
10996
|
-
keyPath: DbIndexConfiguration.keyPath
|
|
11215
|
+
const indexConfiguratioStore = db.createObjectStore(DbIndexConfiguration.store, {
|
|
11216
|
+
keyPath: DbIndexConfiguration.keyPath,
|
|
11217
|
+
autoIncrement: true
|
|
10997
11218
|
});
|
|
10998
|
-
|
|
11219
|
+
indexConfiguratioStore.createIndex(DbIndexConfiguration.collectionGroupIndex, DbIndexConfiguration.collectionGroupIndexPath, { unique: false });
|
|
11220
|
+
const indexStateStore = db.createObjectStore(DbIndexState.store, {
|
|
10999
11221
|
keyPath: DbIndexState.keyPath
|
|
11000
11222
|
});
|
|
11001
|
-
|
|
11002
|
-
|
|
11223
|
+
indexStateStore.createIndex(DbIndexState.sequenceNumberIndex, DbIndexState.sequenceNumberIndexPath, { unique: false });
|
|
11224
|
+
db.createObjectStore(DbIndexEntry.store, {
|
|
11225
|
+
keyPath: DbIndexEntry.keyPath
|
|
11003
11226
|
});
|
|
11004
11227
|
}
|
|
11005
11228
|
|
|
@@ -11112,7 +11335,7 @@ class IndexedDbPersistence {
|
|
|
11112
11335
|
* If set to true, forcefully obtains database access. Existing tabs will
|
|
11113
11336
|
* no longer be able to access IndexedDB.
|
|
11114
11337
|
*/
|
|
11115
|
-
forceOwningTab) {
|
|
11338
|
+
forceOwningTab, schemaVersion = SCHEMA_VERSION) {
|
|
11116
11339
|
this.allowTabSynchronization = allowTabSynchronization;
|
|
11117
11340
|
this.persistenceKey = persistenceKey;
|
|
11118
11341
|
this.clientId = clientId;
|
|
@@ -11121,6 +11344,7 @@ class IndexedDbPersistence {
|
|
|
11121
11344
|
this.document = document;
|
|
11122
11345
|
this.sequenceNumberSyncer = sequenceNumberSyncer;
|
|
11123
11346
|
this.forceOwningTab = forceOwningTab;
|
|
11347
|
+
this.schemaVersion = schemaVersion;
|
|
11124
11348
|
this.listenSequence = null;
|
|
11125
11349
|
this._started = false;
|
|
11126
11350
|
this.isPrimary = false;
|
|
@@ -11142,10 +11366,9 @@ class IndexedDbPersistence {
|
|
|
11142
11366
|
this.referenceDelegate = new IndexedDbLruDelegateImpl(this, lruParams);
|
|
11143
11367
|
this.dbName = persistenceKey + MAIN_DATABASE;
|
|
11144
11368
|
this.serializer = new LocalSerializer(serializer);
|
|
11145
|
-
this.simpleDb = new SimpleDb(this.dbName,
|
|
11369
|
+
this.simpleDb = new SimpleDb(this.dbName, this.schemaVersion, new SchemaConverter(this.serializer));
|
|
11146
11370
|
this.targetCache = new IndexedDbTargetCache(this.referenceDelegate, this.serializer);
|
|
11147
|
-
this.
|
|
11148
|
-
this.remoteDocumentCache = newIndexedDbRemoteDocumentCache(this.serializer, this.indexManager);
|
|
11371
|
+
this.remoteDocumentCache = newIndexedDbRemoteDocumentCache(this.serializer);
|
|
11149
11372
|
this.bundleCache = new IndexedDbBundleCache();
|
|
11150
11373
|
if (this.window && this.window.localStorage) {
|
|
11151
11374
|
this.webStorage = this.window.localStorage;
|
|
@@ -11481,8 +11704,8 @@ class IndexedDbPersistence {
|
|
|
11481
11704
|
get started() {
|
|
11482
11705
|
return this._started;
|
|
11483
11706
|
}
|
|
11484
|
-
getMutationQueue(user) {
|
|
11485
|
-
return IndexedDbMutationQueue.forUser(user, this.serializer,
|
|
11707
|
+
getMutationQueue(user, indexManager) {
|
|
11708
|
+
return IndexedDbMutationQueue.forUser(user, this.serializer, indexManager, this.referenceDelegate);
|
|
11486
11709
|
}
|
|
11487
11710
|
getTargetCache() {
|
|
11488
11711
|
return this.targetCache;
|
|
@@ -11490,8 +11713,8 @@ class IndexedDbPersistence {
|
|
|
11490
11713
|
getRemoteDocumentCache() {
|
|
11491
11714
|
return this.remoteDocumentCache;
|
|
11492
11715
|
}
|
|
11493
|
-
getIndexManager() {
|
|
11494
|
-
return
|
|
11716
|
+
getIndexManager(user) {
|
|
11717
|
+
return new IndexedDbIndexManager(user);
|
|
11495
11718
|
}
|
|
11496
11719
|
getBundleCache() {
|
|
11497
11720
|
return this.bundleCache;
|
|
@@ -11499,11 +11722,12 @@ class IndexedDbPersistence {
|
|
|
11499
11722
|
runTransaction(action, mode, transactionOperation) {
|
|
11500
11723
|
logDebug(LOG_TAG$d, 'Starting transaction:', action);
|
|
11501
11724
|
const simpleDbMode = mode === 'readonly' ? 'readonly' : 'readwrite';
|
|
11725
|
+
const objectStores = getObjectStores(this.schemaVersion);
|
|
11502
11726
|
let persistenceTransaction;
|
|
11503
11727
|
// Do all transactions as readwrite against all object stores, since we
|
|
11504
11728
|
// are the only reader/writer.
|
|
11505
11729
|
return this.simpleDb
|
|
11506
|
-
.runTransaction(action, simpleDbMode,
|
|
11730
|
+
.runTransaction(action, simpleDbMode, objectStores, simpleDbTxn => {
|
|
11507
11731
|
persistenceTransaction = new IndexedDbTransaction(simpleDbTxn, this.listenSequence
|
|
11508
11732
|
? this.listenSequence.next()
|
|
11509
11733
|
: ListenSequence.INVALID);
|
|
@@ -11875,39 +12099,28 @@ class LocalDocumentsView {
|
|
|
11875
12099
|
getDocumentsMatchingCollectionQuery(transaction, query, sinceReadTime) {
|
|
11876
12100
|
// Query the remote documents and overlay mutations.
|
|
11877
12101
|
let results;
|
|
11878
|
-
let mutationBatches;
|
|
11879
12102
|
return this.remoteDocumentCache
|
|
11880
|
-
.
|
|
12103
|
+
.getAll(transaction, query.path, sinceReadTime)
|
|
11881
12104
|
.next(queryResults => {
|
|
11882
12105
|
results = queryResults;
|
|
11883
12106
|
return this.mutationQueue.getAllMutationBatchesAffectingQuery(transaction, query);
|
|
11884
12107
|
})
|
|
11885
|
-
.next(
|
|
11886
|
-
mutationBatches
|
|
11887
|
-
|
|
11888
|
-
|
|
11889
|
-
|
|
11890
|
-
|
|
11891
|
-
|
|
11892
|
-
|
|
11893
|
-
|
|
11894
|
-
|
|
11895
|
-
|
|
11896
|
-
|
|
11897
|
-
|
|
11898
|
-
let document = results.get(key);
|
|
11899
|
-
if (document == null) {
|
|
11900
|
-
// Create invalid document to apply mutations on top of
|
|
11901
|
-
document = MutableDocument.newInvalidDocument(key);
|
|
11902
|
-
results = results.insert(key, document);
|
|
11903
|
-
}
|
|
11904
|
-
mutationApplyToLocalView(mutation, document, batch.localWriteTime);
|
|
11905
|
-
if (!document.isFoundDocument()) {
|
|
11906
|
-
results = results.remove(key);
|
|
11907
|
-
}
|
|
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);
|
|
11908
12121
|
}
|
|
11909
12122
|
}
|
|
11910
|
-
}
|
|
12123
|
+
}
|
|
11911
12124
|
})
|
|
11912
12125
|
.next(() => {
|
|
11913
12126
|
// Finally, filter out any documents that don't actually match
|
|
@@ -11920,29 +12133,6 @@ class LocalDocumentsView {
|
|
|
11920
12133
|
return results;
|
|
11921
12134
|
});
|
|
11922
12135
|
}
|
|
11923
|
-
addMissingBaseDocuments(transaction, matchingMutationBatches, existingDocuments) {
|
|
11924
|
-
let missingBaseDocEntriesForPatching = documentKeySet();
|
|
11925
|
-
for (const batch of matchingMutationBatches) {
|
|
11926
|
-
for (const mutation of batch.mutations) {
|
|
11927
|
-
if (mutation instanceof PatchMutation &&
|
|
11928
|
-
existingDocuments.get(mutation.key) === null) {
|
|
11929
|
-
missingBaseDocEntriesForPatching =
|
|
11930
|
-
missingBaseDocEntriesForPatching.add(mutation.key);
|
|
11931
|
-
}
|
|
11932
|
-
}
|
|
11933
|
-
}
|
|
11934
|
-
let mergedDocuments = existingDocuments;
|
|
11935
|
-
return this.remoteDocumentCache
|
|
11936
|
-
.getEntries(transaction, missingBaseDocEntriesForPatching)
|
|
11937
|
-
.next(missingBaseDocs => {
|
|
11938
|
-
missingBaseDocs.forEach((key, doc) => {
|
|
11939
|
-
if (doc.isFoundDocument()) {
|
|
11940
|
-
mergedDocuments = mergedDocuments.insert(key, doc);
|
|
11941
|
-
}
|
|
11942
|
-
});
|
|
11943
|
-
return mergedDocuments;
|
|
11944
|
-
});
|
|
11945
|
-
}
|
|
11946
12136
|
}
|
|
11947
12137
|
|
|
11948
12138
|
/**
|
|
@@ -12001,11 +12191,18 @@ class LocalStoreImpl {
|
|
|
12001
12191
|
* PORTING NOTE: This is only used for multi-tab synchronization.
|
|
12002
12192
|
*/
|
|
12003
12193
|
this.lastDocumentChangeReadTime = SnapshotVersion.min();
|
|
12004
|
-
this.mutationQueue = persistence.getMutationQueue(initialUser);
|
|
12005
12194
|
this.remoteDocuments = persistence.getRemoteDocumentCache();
|
|
12006
12195
|
this.targetCache = persistence.getTargetCache();
|
|
12007
|
-
this.localDocuments = new LocalDocumentsView(this.remoteDocuments, this.mutationQueue, this.persistence.getIndexManager());
|
|
12008
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);
|
|
12009
12206
|
this.queryEngine.setLocalDocumentsView(this.localDocuments);
|
|
12010
12207
|
}
|
|
12011
12208
|
collectGarbage(garbageCollector) {
|
|
@@ -12027,8 +12224,6 @@ persistence, queryEngine, initialUser, serializer) {
|
|
|
12027
12224
|
// change.
|
|
12028
12225
|
async function localStoreHandleUserChange(localStore, user) {
|
|
12029
12226
|
const localStoreImpl = debugCast(localStore);
|
|
12030
|
-
let newMutationQueue = localStoreImpl.mutationQueue;
|
|
12031
|
-
let newLocalDocuments = localStoreImpl.localDocuments;
|
|
12032
12227
|
const result = await localStoreImpl.persistence.runTransaction('Handle user change', 'readonly', txn => {
|
|
12033
12228
|
// Swap out the mutation queue, grabbing the pending mutation batches
|
|
12034
12229
|
// before and after.
|
|
@@ -12037,11 +12232,8 @@ async function localStoreHandleUserChange(localStore, user) {
|
|
|
12037
12232
|
.getAllMutationBatches(txn)
|
|
12038
12233
|
.next(promisedOldBatches => {
|
|
12039
12234
|
oldBatches = promisedOldBatches;
|
|
12040
|
-
|
|
12041
|
-
|
|
12042
|
-
// MutationQueue.
|
|
12043
|
-
newLocalDocuments = new LocalDocumentsView(localStoreImpl.remoteDocuments, newMutationQueue, localStoreImpl.persistence.getIndexManager());
|
|
12044
|
-
return newMutationQueue.getAllMutationBatches(txn);
|
|
12235
|
+
localStoreImpl.initializeUserComponents(user);
|
|
12236
|
+
return localStoreImpl.mutationQueue.getAllMutationBatches(txn);
|
|
12045
12237
|
})
|
|
12046
12238
|
.next(newBatches => {
|
|
12047
12239
|
const removedBatchIds = [];
|
|
@@ -12062,7 +12254,7 @@ async function localStoreHandleUserChange(localStore, user) {
|
|
|
12062
12254
|
}
|
|
12063
12255
|
// Return the set of all (potentially) changed documents and the list
|
|
12064
12256
|
// of mutation batch IDs that were affected by change.
|
|
12065
|
-
return
|
|
12257
|
+
return localStoreImpl.localDocuments
|
|
12066
12258
|
.getDocuments(txn, changedKeys)
|
|
12067
12259
|
.next(affectedDocuments => {
|
|
12068
12260
|
return {
|
|
@@ -12073,9 +12265,6 @@ async function localStoreHandleUserChange(localStore, user) {
|
|
|
12073
12265
|
});
|
|
12074
12266
|
});
|
|
12075
12267
|
});
|
|
12076
|
-
localStoreImpl.mutationQueue = newMutationQueue;
|
|
12077
|
-
localStoreImpl.localDocuments = newLocalDocuments;
|
|
12078
|
-
localStoreImpl.queryEngine.setLocalDocumentsView(localStoreImpl.localDocuments);
|
|
12079
12268
|
return result;
|
|
12080
12269
|
}
|
|
12081
12270
|
/* Accepts locally generated Mutations and commit them to storage. */
|
|
@@ -13141,14 +13330,16 @@ class MemoryRemoteDocumentCacheImpl {
|
|
|
13141
13330
|
* expected to just return 0 to avoid unnecessarily doing the work of
|
|
13142
13331
|
* calculating the size.
|
|
13143
13332
|
*/
|
|
13144
|
-
constructor(
|
|
13145
|
-
this.indexManager = indexManager;
|
|
13333
|
+
constructor(sizer) {
|
|
13146
13334
|
this.sizer = sizer;
|
|
13147
13335
|
/** Underlying cache of documents and their read times. */
|
|
13148
13336
|
this.docs = documentEntryMap();
|
|
13149
13337
|
/** Size of all cached documents. */
|
|
13150
13338
|
this.size = 0;
|
|
13151
13339
|
}
|
|
13340
|
+
setIndexManager(indexManager) {
|
|
13341
|
+
this.indexManager = indexManager;
|
|
13342
|
+
}
|
|
13152
13343
|
/**
|
|
13153
13344
|
* Adds the supplied entry to the cache and updates the cache size as appropriate.
|
|
13154
13345
|
*
|
|
@@ -13196,21 +13387,22 @@ class MemoryRemoteDocumentCacheImpl {
|
|
|
13196
13387
|
});
|
|
13197
13388
|
return PersistencePromise.resolve(results);
|
|
13198
13389
|
}
|
|
13199
|
-
|
|
13390
|
+
getAll(transaction, collectionPath, sinceReadTime) {
|
|
13200
13391
|
let results = mutableDocumentMap();
|
|
13201
13392
|
// Documents are ordered by key, so we can use a prefix scan to narrow down
|
|
13202
13393
|
// the documents we need to match the query against.
|
|
13203
|
-
const prefix = new DocumentKey(
|
|
13394
|
+
const prefix = new DocumentKey(collectionPath.child(''));
|
|
13204
13395
|
const iterator = this.docs.getIteratorFrom(prefix);
|
|
13205
13396
|
while (iterator.hasNext()) {
|
|
13206
13397
|
const { key, value: { document } } = iterator.getNext();
|
|
13207
|
-
if (!
|
|
13398
|
+
if (!collectionPath.isPrefixOf(key.path)) {
|
|
13208
13399
|
break;
|
|
13209
13400
|
}
|
|
13210
|
-
if (
|
|
13401
|
+
if (key.path.length > collectionPath.length + 1) {
|
|
13402
|
+
// Exclude entries from subcollections.
|
|
13211
13403
|
continue;
|
|
13212
13404
|
}
|
|
13213
|
-
if (
|
|
13405
|
+
if (document.readTime.compareTo(sinceReadTime) <= 0) {
|
|
13214
13406
|
continue;
|
|
13215
13407
|
}
|
|
13216
13408
|
results = results.insert(document.key, document.mutableCopy());
|
|
@@ -13232,13 +13424,12 @@ class MemoryRemoteDocumentCacheImpl {
|
|
|
13232
13424
|
/**
|
|
13233
13425
|
* Creates a new memory-only RemoteDocumentCache.
|
|
13234
13426
|
*
|
|
13235
|
-
* @param indexManager - A class that manages collection group indices.
|
|
13236
13427
|
* @param sizer - Used to assess the size of a document. For eager GC, this is
|
|
13237
13428
|
* expected to just return 0 to avoid unnecessarily doing the work of
|
|
13238
13429
|
* calculating the size.
|
|
13239
13430
|
*/
|
|
13240
|
-
function newMemoryRemoteDocumentCache(
|
|
13241
|
-
return new MemoryRemoteDocumentCacheImpl(
|
|
13431
|
+
function newMemoryRemoteDocumentCache(sizer) {
|
|
13432
|
+
return new MemoryRemoteDocumentCacheImpl(sizer);
|
|
13242
13433
|
}
|
|
13243
13434
|
/**
|
|
13244
13435
|
* Handles the details of adding and updating documents in the MemoryRemoteDocumentCache.
|
|
@@ -13439,7 +13630,7 @@ class MemoryPersistence {
|
|
|
13439
13630
|
this.targetCache = new MemoryTargetCache(this);
|
|
13440
13631
|
const sizer = (doc) => this.referenceDelegate.documentSize(doc);
|
|
13441
13632
|
this.indexManager = new MemoryIndexManager();
|
|
13442
|
-
this.remoteDocumentCache = newMemoryRemoteDocumentCache(
|
|
13633
|
+
this.remoteDocumentCache = newMemoryRemoteDocumentCache(sizer);
|
|
13443
13634
|
this.serializer = new LocalSerializer(serializer);
|
|
13444
13635
|
this.bundleCache = new MemoryBundleCache(this.serializer);
|
|
13445
13636
|
}
|
|
@@ -13460,13 +13651,15 @@ class MemoryPersistence {
|
|
|
13460
13651
|
setNetworkEnabled() {
|
|
13461
13652
|
// No op.
|
|
13462
13653
|
}
|
|
13463
|
-
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.
|
|
13464
13657
|
return this.indexManager;
|
|
13465
13658
|
}
|
|
13466
|
-
getMutationQueue(user) {
|
|
13659
|
+
getMutationQueue(user, indexManager) {
|
|
13467
13660
|
let queue = this.mutationQueues[user.toKey()];
|
|
13468
13661
|
if (!queue) {
|
|
13469
|
-
queue = new MemoryMutationQueue(
|
|
13662
|
+
queue = new MemoryMutationQueue(indexManager, this.referenceDelegate);
|
|
13470
13663
|
this.mutationQueues[user.toKey()] = queue;
|
|
13471
13664
|
}
|
|
13472
13665
|
return queue;
|
|
@@ -20429,12 +20622,12 @@ async function syncEngineListen(syncEngine, query) {
|
|
|
20429
20622
|
}
|
|
20430
20623
|
else {
|
|
20431
20624
|
const targetData = await localStoreAllocateTarget(syncEngineImpl.localStore, queryToTarget(query));
|
|
20432
|
-
const status = syncEngineImpl.sharedClientState.addLocalQueryTarget(targetData.targetId);
|
|
20433
|
-
targetId = targetData.targetId;
|
|
20434
|
-
viewSnapshot = await initializeViewAndComputeSnapshot(syncEngineImpl, query, targetId, status === 'current');
|
|
20435
20625
|
if (syncEngineImpl.isPrimaryClient) {
|
|
20436
20626
|
remoteStoreListen(syncEngineImpl.remoteStore, targetData);
|
|
20437
20627
|
}
|
|
20628
|
+
const status = syncEngineImpl.sharedClientState.addLocalQueryTarget(targetData.targetId);
|
|
20629
|
+
targetId = targetData.targetId;
|
|
20630
|
+
viewSnapshot = await initializeViewAndComputeSnapshot(syncEngineImpl, query, targetId, status === 'current');
|
|
20438
20631
|
}
|
|
20439
20632
|
return viewSnapshot;
|
|
20440
20633
|
}
|
|
@@ -24942,8 +25135,7 @@ class DocumentSnapshot extends DocumentSnapshot$1 {
|
|
|
24942
25135
|
this.metadata = metadata;
|
|
24943
25136
|
}
|
|
24944
25137
|
/**
|
|
24945
|
-
*
|
|
24946
|
-
* exists. True if the document exists.
|
|
25138
|
+
* Returns whether or not the data exists. True if the document exists.
|
|
24947
25139
|
*/
|
|
24948
25140
|
exists() {
|
|
24949
25141
|
return super.exists();
|
|
@@ -25317,51 +25509,53 @@ function limitToLast(limit) {
|
|
|
25317
25509
|
return new QueryLimitConstraint('limitToLast', limit, "L" /* Last */);
|
|
25318
25510
|
}
|
|
25319
25511
|
class QueryStartAtConstraint extends QueryConstraint {
|
|
25320
|
-
constructor(type, _docOrFields,
|
|
25512
|
+
constructor(type, _docOrFields, _inclusive) {
|
|
25321
25513
|
super();
|
|
25322
25514
|
this.type = type;
|
|
25323
25515
|
this._docOrFields = _docOrFields;
|
|
25324
|
-
this.
|
|
25516
|
+
this._inclusive = _inclusive;
|
|
25325
25517
|
}
|
|
25326
25518
|
_apply(query) {
|
|
25327
|
-
const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this.
|
|
25519
|
+
const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._inclusive);
|
|
25328
25520
|
return new Query(query.firestore, query.converter, queryWithStartAt(query._query, bound));
|
|
25329
25521
|
}
|
|
25330
25522
|
}
|
|
25331
25523
|
function startAt(...docOrFields) {
|
|
25332
|
-
return new QueryStartAtConstraint('startAt', docOrFields,
|
|
25524
|
+
return new QueryStartAtConstraint('startAt', docOrFields,
|
|
25525
|
+
/*inclusive=*/ true);
|
|
25333
25526
|
}
|
|
25334
25527
|
function startAfter(...docOrFields) {
|
|
25335
25528
|
return new QueryStartAtConstraint('startAfter', docOrFields,
|
|
25336
|
-
/*
|
|
25529
|
+
/*inclusive=*/ false);
|
|
25337
25530
|
}
|
|
25338
25531
|
class QueryEndAtConstraint extends QueryConstraint {
|
|
25339
|
-
constructor(type, _docOrFields,
|
|
25532
|
+
constructor(type, _docOrFields, _inclusive) {
|
|
25340
25533
|
super();
|
|
25341
25534
|
this.type = type;
|
|
25342
25535
|
this._docOrFields = _docOrFields;
|
|
25343
|
-
this.
|
|
25536
|
+
this._inclusive = _inclusive;
|
|
25344
25537
|
}
|
|
25345
25538
|
_apply(query) {
|
|
25346
|
-
const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this.
|
|
25539
|
+
const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._inclusive);
|
|
25347
25540
|
return new Query(query.firestore, query.converter, queryWithEndAt(query._query, bound));
|
|
25348
25541
|
}
|
|
25349
25542
|
}
|
|
25350
25543
|
function endBefore(...docOrFields) {
|
|
25351
|
-
return new QueryEndAtConstraint('endBefore', docOrFields,
|
|
25544
|
+
return new QueryEndAtConstraint('endBefore', docOrFields,
|
|
25545
|
+
/*inclusive=*/ false);
|
|
25352
25546
|
}
|
|
25353
25547
|
function endAt(...docOrFields) {
|
|
25354
|
-
return new QueryEndAtConstraint('endAt', docOrFields, /*
|
|
25548
|
+
return new QueryEndAtConstraint('endAt', docOrFields, /*inclusive=*/ true);
|
|
25355
25549
|
}
|
|
25356
25550
|
/** Helper function to create a bound from a document or fields */
|
|
25357
|
-
function newQueryBoundFromDocOrFields(query, methodName, docOrFields,
|
|
25551
|
+
function newQueryBoundFromDocOrFields(query, methodName, docOrFields, inclusive) {
|
|
25358
25552
|
docOrFields[0] = util$1.getModularInstance(docOrFields[0]);
|
|
25359
25553
|
if (docOrFields[0] instanceof DocumentSnapshot$1) {
|
|
25360
|
-
return newQueryBoundFromDocument(query._query, query.firestore._databaseId, methodName, docOrFields[0]._document,
|
|
25554
|
+
return newQueryBoundFromDocument(query._query, query.firestore._databaseId, methodName, docOrFields[0]._document, inclusive);
|
|
25361
25555
|
}
|
|
25362
25556
|
else {
|
|
25363
25557
|
const reader = newUserDataReader(query.firestore);
|
|
25364
|
-
return newQueryBoundFromFields(query._query, query.firestore._databaseId, reader, methodName, docOrFields,
|
|
25558
|
+
return newQueryBoundFromFields(query._query, query.firestore._databaseId, reader, methodName, docOrFields, inclusive);
|
|
25365
25559
|
}
|
|
25366
25560
|
}
|
|
25367
25561
|
function newQueryFilter(query, methodName, dataReader, databaseId, fieldPath, op, value) {
|
|
@@ -25419,7 +25613,7 @@ function newQueryOrderBy(query, fieldPath, direction) {
|
|
|
25419
25613
|
* of the query or if any of the fields in the order by are an uncommitted
|
|
25420
25614
|
* server timestamp.
|
|
25421
25615
|
*/
|
|
25422
|
-
function newQueryBoundFromDocument(query, databaseId, methodName, doc,
|
|
25616
|
+
function newQueryBoundFromDocument(query, databaseId, methodName, doc, inclusive) {
|
|
25423
25617
|
if (!doc) {
|
|
25424
25618
|
throw new FirestoreError(Code.NOT_FOUND, `Can't use a DocumentSnapshot that doesn't exist for ` +
|
|
25425
25619
|
`${methodName}().`);
|
|
@@ -25456,12 +25650,12 @@ function newQueryBoundFromDocument(query, databaseId, methodName, doc, before) {
|
|
|
25456
25650
|
}
|
|
25457
25651
|
}
|
|
25458
25652
|
}
|
|
25459
|
-
return new Bound(components,
|
|
25653
|
+
return new Bound(components, inclusive);
|
|
25460
25654
|
}
|
|
25461
25655
|
/**
|
|
25462
25656
|
* Converts a list of field values to a `Bound` for the given query.
|
|
25463
25657
|
*/
|
|
25464
|
-
function newQueryBoundFromFields(query, databaseId, dataReader, methodName, values,
|
|
25658
|
+
function newQueryBoundFromFields(query, databaseId, dataReader, methodName, values, inclusive) {
|
|
25465
25659
|
// Use explicit order by's because it has to match the query the user made
|
|
25466
25660
|
const orderBy = query.explicitOrderBy;
|
|
25467
25661
|
if (values.length > orderBy.length) {
|
|
@@ -25498,7 +25692,7 @@ function newQueryBoundFromFields(query, databaseId, dataReader, methodName, valu
|
|
|
25498
25692
|
components.push(wrapped);
|
|
25499
25693
|
}
|
|
25500
25694
|
}
|
|
25501
|
-
return new Bound(components,
|
|
25695
|
+
return new Bound(components, inclusive);
|
|
25502
25696
|
}
|
|
25503
25697
|
/**
|
|
25504
25698
|
* Parses the given `documentIdValue` into a `ReferenceValue`, throwing
|