@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.mjs
CHANGED
|
@@ -8,7 +8,7 @@ import { credentials, loadPackageDefinition, Metadata } from '@grpc/grpc-js';
|
|
|
8
8
|
import { fromJSON } from '@grpc/proto-loader';
|
|
9
9
|
|
|
10
10
|
const name = "@firebase/firestore";
|
|
11
|
-
const version$1 = "3.4.4-canary.
|
|
11
|
+
const version$1 = "3.4.4-canary.50de44c2e";
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* @license
|
|
@@ -61,7 +61,7 @@ User.GOOGLE_CREDENTIALS = new User('google-credentials-uid');
|
|
|
61
61
|
User.FIRST_PARTY = new User('first-party-uid');
|
|
62
62
|
User.MOCK_USER = new User('mock-user');
|
|
63
63
|
|
|
64
|
-
const version = "9.6.
|
|
64
|
+
const version = "9.6.6-canary.50de44c2e";
|
|
65
65
|
|
|
66
66
|
/**
|
|
67
67
|
* @license
|
|
@@ -1774,7 +1774,10 @@ DbNamedQuery.keyPath = 'name';
|
|
|
1774
1774
|
/** An object representing the global configuration for a field index. */
|
|
1775
1775
|
class DbIndexConfiguration {
|
|
1776
1776
|
constructor(
|
|
1777
|
-
/**
|
|
1777
|
+
/**
|
|
1778
|
+
* The index id for this entry. Undefined for indexes that are not yet
|
|
1779
|
+
* persisted.
|
|
1780
|
+
*/
|
|
1778
1781
|
indexId,
|
|
1779
1782
|
/** The collection group this index belongs to. */
|
|
1780
1783
|
collectionGroup,
|
|
@@ -1788,6 +1791,16 @@ class DbIndexConfiguration {
|
|
|
1788
1791
|
/** Name of the IndexedDb object store. */
|
|
1789
1792
|
DbIndexConfiguration.store = 'indexConfiguration';
|
|
1790
1793
|
DbIndexConfiguration.keyPath = 'indexId';
|
|
1794
|
+
/**
|
|
1795
|
+
* An index that provides access to the index configurations by collection
|
|
1796
|
+
* group.
|
|
1797
|
+
*
|
|
1798
|
+
* PORTING NOTE: iOS and Android maintain this index in-memory, but this is
|
|
1799
|
+
* not possible here as the Web client supports concurrent access to
|
|
1800
|
+
* persistence via multi-tab.
|
|
1801
|
+
*/
|
|
1802
|
+
DbIndexConfiguration.collectionGroupIndex = 'collectionGroupIndex';
|
|
1803
|
+
DbIndexConfiguration.collectionGroupIndexPath = 'collectionGroup';
|
|
1791
1804
|
/**
|
|
1792
1805
|
* An object describing how up-to-date the index backfill is for each user and
|
|
1793
1806
|
* index.
|
|
@@ -1829,8 +1842,18 @@ class DbIndexState {
|
|
|
1829
1842
|
/** Name of the IndexedDb object store. */
|
|
1830
1843
|
DbIndexState.store = 'indexState';
|
|
1831
1844
|
DbIndexState.keyPath = ['indexId', 'uid'];
|
|
1845
|
+
/**
|
|
1846
|
+
* An index that provides access to documents in a collection sorted by last
|
|
1847
|
+
* update time. Used by the backfiller.
|
|
1848
|
+
*
|
|
1849
|
+
* PORTING NOTE: iOS and Android maintain this index in-memory, but this is
|
|
1850
|
+
* not possible here as the Web client supports concurrent access to
|
|
1851
|
+
* persistence via multi-tab.
|
|
1852
|
+
*/
|
|
1853
|
+
DbIndexState.sequenceNumberIndex = 'sequenceNumberIndex';
|
|
1854
|
+
DbIndexState.sequenceNumberIndexPath = ['uid', 'sequenceNumber'];
|
|
1832
1855
|
/** An object that stores the encoded entries for all documents and fields. */
|
|
1833
|
-
class
|
|
1856
|
+
class DbIndexEntry {
|
|
1834
1857
|
constructor(
|
|
1835
1858
|
/** The index id for this entry. */
|
|
1836
1859
|
indexId,
|
|
@@ -1850,8 +1873,8 @@ class DbIndexEntries {
|
|
|
1850
1873
|
}
|
|
1851
1874
|
}
|
|
1852
1875
|
/** Name of the IndexedDb object store. */
|
|
1853
|
-
|
|
1854
|
-
|
|
1876
|
+
DbIndexEntry.store = 'indexEntries';
|
|
1877
|
+
DbIndexEntry.keyPath = [
|
|
1855
1878
|
'indexId',
|
|
1856
1879
|
'uid',
|
|
1857
1880
|
'arrayValue',
|
|
@@ -1881,18 +1904,24 @@ const V8_STORES = [...V6_STORES, DbCollectionParent.store];
|
|
|
1881
1904
|
// V9 does not change the set of stores.
|
|
1882
1905
|
// V10 does not change the set of stores.
|
|
1883
1906
|
const V11_STORES = [...V8_STORES, DbBundle.store, DbNamedQuery.store];
|
|
1884
|
-
[
|
|
1907
|
+
const V12_STORES = [
|
|
1885
1908
|
...V11_STORES,
|
|
1886
1909
|
DbIndexConfiguration.store,
|
|
1887
1910
|
DbIndexState.store,
|
|
1888
|
-
|
|
1911
|
+
DbIndexEntry.store
|
|
1889
1912
|
];
|
|
1890
|
-
/**
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1913
|
+
/** Returns the object stores for the provided schema. */
|
|
1914
|
+
function getObjectStores(schemaVersion) {
|
|
1915
|
+
if (schemaVersion === 12) {
|
|
1916
|
+
return V12_STORES;
|
|
1917
|
+
}
|
|
1918
|
+
else if (schemaVersion === 11) {
|
|
1919
|
+
return V11_STORES;
|
|
1920
|
+
}
|
|
1921
|
+
else {
|
|
1922
|
+
fail();
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1896
1925
|
|
|
1897
1926
|
/**
|
|
1898
1927
|
* @license
|
|
@@ -2189,6 +2218,15 @@ class SimpleDbTransaction {
|
|
|
2189
2218
|
this.transaction.abort();
|
|
2190
2219
|
}
|
|
2191
2220
|
}
|
|
2221
|
+
maybeCommit() {
|
|
2222
|
+
// If the browser supports V3 IndexedDB, we invoke commit() explicitly to
|
|
2223
|
+
// speed up index DB processing if the event loop remains blocks.
|
|
2224
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2225
|
+
const maybeV3IndexedDb = this.transaction;
|
|
2226
|
+
if (!this.aborted && typeof maybeV3IndexedDb.commit === 'function') {
|
|
2227
|
+
maybeV3IndexedDb.commit();
|
|
2228
|
+
}
|
|
2229
|
+
}
|
|
2192
2230
|
/**
|
|
2193
2231
|
* Returns a SimpleDbStore<KeyType, ValueType> for the specified store. All
|
|
2194
2232
|
* operations performed on the SimpleDbStore happen within the context of this
|
|
@@ -2385,6 +2423,10 @@ class SimpleDb {
|
|
|
2385
2423
|
this.db = await this.ensureDb(action);
|
|
2386
2424
|
const transaction = SimpleDbTransaction.open(this.db, action, readonly ? 'readonly' : 'readwrite', objectStores);
|
|
2387
2425
|
const transactionFnResult = transactionFn(transaction)
|
|
2426
|
+
.next(result => {
|
|
2427
|
+
transaction.maybeCommit();
|
|
2428
|
+
return result;
|
|
2429
|
+
})
|
|
2388
2430
|
.catch(error => {
|
|
2389
2431
|
// Abort the transaction if there was an error.
|
|
2390
2432
|
transaction.abort(error);
|
|
@@ -2557,13 +2599,29 @@ class SimpleDbStore {
|
|
|
2557
2599
|
return wrapRequest(request);
|
|
2558
2600
|
}
|
|
2559
2601
|
loadAll(indexOrRange, range) {
|
|
2560
|
-
const
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
return
|
|
2566
|
-
|
|
2602
|
+
const iterateOptions = this.options(indexOrRange, range);
|
|
2603
|
+
// Use `getAll()` if the browser supports IndexedDB v3, as it is roughly
|
|
2604
|
+
// 20% faster. Unfortunately, getAll() does not support custom indices.
|
|
2605
|
+
if (!iterateOptions.index && typeof this.store.getAll === 'function') {
|
|
2606
|
+
const request = this.store.getAll(iterateOptions.range);
|
|
2607
|
+
return new PersistencePromise((resolve, reject) => {
|
|
2608
|
+
request.onerror = (event) => {
|
|
2609
|
+
reject(event.target.error);
|
|
2610
|
+
};
|
|
2611
|
+
request.onsuccess = (event) => {
|
|
2612
|
+
resolve(event.target.result);
|
|
2613
|
+
};
|
|
2614
|
+
});
|
|
2615
|
+
}
|
|
2616
|
+
else {
|
|
2617
|
+
const cursor = this.cursor(iterateOptions);
|
|
2618
|
+
const results = [];
|
|
2619
|
+
return this.iterateCursor(cursor, (key, value) => {
|
|
2620
|
+
results.push(value);
|
|
2621
|
+
}).next(() => {
|
|
2622
|
+
return results;
|
|
2623
|
+
});
|
|
2624
|
+
}
|
|
2567
2625
|
}
|
|
2568
2626
|
deleteAll(indexOrRange, range) {
|
|
2569
2627
|
logDebug(LOG_TAG$g, 'DELETE ALL', this.store.name);
|
|
@@ -4417,12 +4475,12 @@ class FieldIndex {
|
|
|
4417
4475
|
/** The collection ID this index applies to. */
|
|
4418
4476
|
collectionGroup,
|
|
4419
4477
|
/** The field segments for this index. */
|
|
4420
|
-
|
|
4478
|
+
fields,
|
|
4421
4479
|
/** Shows how up-to-date the index is for the current user. */
|
|
4422
4480
|
indexState) {
|
|
4423
4481
|
this.indexId = indexId;
|
|
4424
4482
|
this.collectionGroup = collectionGroup;
|
|
4425
|
-
this.
|
|
4483
|
+
this.fields = fields;
|
|
4426
4484
|
this.indexState = indexState;
|
|
4427
4485
|
}
|
|
4428
4486
|
}
|
|
@@ -4532,27 +4590,29 @@ function newTarget(path, collectionGroup = null, orderBy = [], filters = [], lim
|
|
|
4532
4590
|
function canonifyTarget(target) {
|
|
4533
4591
|
const targetImpl = debugCast(target);
|
|
4534
4592
|
if (targetImpl.memoizedCanonicalId === null) {
|
|
4535
|
-
let
|
|
4593
|
+
let str = targetImpl.path.canonicalString();
|
|
4536
4594
|
if (targetImpl.collectionGroup !== null) {
|
|
4537
|
-
|
|
4595
|
+
str += '|cg:' + targetImpl.collectionGroup;
|
|
4538
4596
|
}
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4597
|
+
str += '|f:';
|
|
4598
|
+
str += targetImpl.filters.map(f => canonifyFilter(f)).join(',');
|
|
4599
|
+
str += '|ob:';
|
|
4600
|
+
str += targetImpl.orderBy.map(o => canonifyOrderBy(o)).join(',');
|
|
4543
4601
|
if (!isNullOrUndefined(targetImpl.limit)) {
|
|
4544
|
-
|
|
4545
|
-
|
|
4602
|
+
str += '|l:';
|
|
4603
|
+
str += targetImpl.limit;
|
|
4546
4604
|
}
|
|
4547
4605
|
if (targetImpl.startAt) {
|
|
4548
|
-
|
|
4549
|
-
|
|
4606
|
+
str += '|lb:';
|
|
4607
|
+
str += targetImpl.startAt.inclusive ? 'b:' : 'a:';
|
|
4608
|
+
str += targetImpl.startAt.position.map(p => canonicalId(p)).join(',');
|
|
4550
4609
|
}
|
|
4551
4610
|
if (targetImpl.endAt) {
|
|
4552
|
-
|
|
4553
|
-
|
|
4611
|
+
str += '|ub:';
|
|
4612
|
+
str += targetImpl.endAt.inclusive ? 'a:' : 'b:';
|
|
4613
|
+
str += targetImpl.endAt.position.map(p => canonicalId(p)).join(',');
|
|
4554
4614
|
}
|
|
4555
|
-
targetImpl.memoizedCanonicalId =
|
|
4615
|
+
targetImpl.memoizedCanonicalId = str;
|
|
4556
4616
|
}
|
|
4557
4617
|
return targetImpl.memoizedCanonicalId;
|
|
4558
4618
|
}
|
|
@@ -4575,10 +4635,14 @@ function stringifyTarget(target) {
|
|
|
4575
4635
|
.join(', ')}]`;
|
|
4576
4636
|
}
|
|
4577
4637
|
if (target.startAt) {
|
|
4578
|
-
str += ', startAt: '
|
|
4638
|
+
str += ', startAt: ';
|
|
4639
|
+
str += target.startAt.inclusive ? 'b:' : 'a:';
|
|
4640
|
+
str += target.startAt.position.map(p => canonicalId(p)).join(',');
|
|
4579
4641
|
}
|
|
4580
4642
|
if (target.endAt) {
|
|
4581
|
-
str += ', endAt: '
|
|
4643
|
+
str += ', endAt: ';
|
|
4644
|
+
str += target.endAt.inclusive ? 'a:' : 'b:';
|
|
4645
|
+
str += target.endAt.position.map(p => canonicalId(p)).join(',');
|
|
4582
4646
|
}
|
|
4583
4647
|
return `Target(${str})`;
|
|
4584
4648
|
}
|
|
@@ -4801,7 +4865,6 @@ class ArrayContainsAnyFilter extends FieldFilter {
|
|
|
4801
4865
|
return other.arrayValue.values.some(val => arrayValueContains(this.value.arrayValue, val));
|
|
4802
4866
|
}
|
|
4803
4867
|
}
|
|
4804
|
-
// TODO(indexing): Change Bound.before to "inclusive"
|
|
4805
4868
|
/**
|
|
4806
4869
|
* Represents a bound of a query.
|
|
4807
4870
|
*
|
|
@@ -4817,17 +4880,11 @@ class ArrayContainsAnyFilter extends FieldFilter {
|
|
|
4817
4880
|
* just after the provided values.
|
|
4818
4881
|
*/
|
|
4819
4882
|
class Bound {
|
|
4820
|
-
constructor(position,
|
|
4883
|
+
constructor(position, inclusive) {
|
|
4821
4884
|
this.position = position;
|
|
4822
|
-
this.
|
|
4885
|
+
this.inclusive = inclusive;
|
|
4823
4886
|
}
|
|
4824
4887
|
}
|
|
4825
|
-
function canonifyBound(bound) {
|
|
4826
|
-
// TODO(b/29183165): Make this collision robust.
|
|
4827
|
-
return `${bound.before ? 'b' : 'a'}:${bound.position
|
|
4828
|
-
.map(p => canonicalId(p))
|
|
4829
|
-
.join(',')}`;
|
|
4830
|
-
}
|
|
4831
4888
|
/**
|
|
4832
4889
|
* An ordering on a field, in some Direction. Direction defaults to ASCENDING.
|
|
4833
4890
|
*/
|
|
@@ -4847,11 +4904,7 @@ function stringifyOrderBy(orderBy) {
|
|
|
4847
4904
|
function orderByEquals(left, right) {
|
|
4848
4905
|
return left.dir === right.dir && left.field.isEqual(right.field);
|
|
4849
4906
|
}
|
|
4850
|
-
|
|
4851
|
-
* Returns true if a document sorts before a bound using the provided sort
|
|
4852
|
-
* order.
|
|
4853
|
-
*/
|
|
4854
|
-
function sortsBeforeDocument(bound, orderBy, doc) {
|
|
4907
|
+
function boundCompareToDocument(bound, orderBy, doc) {
|
|
4855
4908
|
let comparison = 0;
|
|
4856
4909
|
for (let i = 0; i < bound.position.length; i++) {
|
|
4857
4910
|
const orderByComponent = orderBy[i];
|
|
@@ -4870,7 +4923,23 @@ function sortsBeforeDocument(bound, orderBy, doc) {
|
|
|
4870
4923
|
break;
|
|
4871
4924
|
}
|
|
4872
4925
|
}
|
|
4873
|
-
return
|
|
4926
|
+
return comparison;
|
|
4927
|
+
}
|
|
4928
|
+
/**
|
|
4929
|
+
* Returns true if a document sorts after a bound using the provided sort
|
|
4930
|
+
* order.
|
|
4931
|
+
*/
|
|
4932
|
+
function boundSortsAfterDocument(bound, orderBy, doc) {
|
|
4933
|
+
const comparison = boundCompareToDocument(bound, orderBy, doc);
|
|
4934
|
+
return bound.inclusive ? comparison >= 0 : comparison > 0;
|
|
4935
|
+
}
|
|
4936
|
+
/**
|
|
4937
|
+
* Returns true if a document sorts before a bound using the provided sort
|
|
4938
|
+
* order.
|
|
4939
|
+
*/
|
|
4940
|
+
function boundSortsBeforeDocument(bound, orderBy, doc) {
|
|
4941
|
+
const comparison = boundCompareToDocument(bound, orderBy, doc);
|
|
4942
|
+
return bound.inclusive ? comparison <= 0 : comparison < 0;
|
|
4874
4943
|
}
|
|
4875
4944
|
function boundEquals(left, right) {
|
|
4876
4945
|
if (left === null) {
|
|
@@ -4879,7 +4948,7 @@ function boundEquals(left, right) {
|
|
|
4879
4948
|
else if (right === null) {
|
|
4880
4949
|
return false;
|
|
4881
4950
|
}
|
|
4882
|
-
if (left.
|
|
4951
|
+
if (left.inclusive !== right.inclusive ||
|
|
4883
4952
|
left.position.length !== right.position.length) {
|
|
4884
4953
|
return false;
|
|
4885
4954
|
}
|
|
@@ -5083,10 +5152,10 @@ function queryToTarget(query) {
|
|
|
5083
5152
|
}
|
|
5084
5153
|
// We need to swap the cursors to match the now-flipped query ordering.
|
|
5085
5154
|
const startAt = queryImpl.endAt
|
|
5086
|
-
? new Bound(queryImpl.endAt.position, !queryImpl.endAt.
|
|
5155
|
+
? new Bound(queryImpl.endAt.position, !queryImpl.endAt.inclusive)
|
|
5087
5156
|
: null;
|
|
5088
5157
|
const endAt = queryImpl.startAt
|
|
5089
|
-
? new Bound(queryImpl.startAt.position, !queryImpl.startAt.
|
|
5158
|
+
? new Bound(queryImpl.startAt.position, !queryImpl.startAt.inclusive)
|
|
5090
5159
|
: null;
|
|
5091
5160
|
// Now return as a LimitType.First query.
|
|
5092
5161
|
queryImpl.memoizedTarget = newTarget(queryImpl.path, queryImpl.collectionGroup, orderBys, queryImpl.filters, queryImpl.limit, startAt, endAt);
|
|
@@ -5174,11 +5243,11 @@ function queryMatchesFilters(query, doc) {
|
|
|
5174
5243
|
/** Makes sure a document is within the bounds, if provided. */
|
|
5175
5244
|
function queryMatchesBounds(query, doc) {
|
|
5176
5245
|
if (query.startAt &&
|
|
5177
|
-
!
|
|
5246
|
+
!boundSortsBeforeDocument(query.startAt, queryOrderBy(query), doc)) {
|
|
5178
5247
|
return false;
|
|
5179
5248
|
}
|
|
5180
5249
|
if (query.endAt &&
|
|
5181
|
-
|
|
5250
|
+
!boundSortsAfterDocument(query.endAt, queryOrderBy(query), doc)) {
|
|
5182
5251
|
return false;
|
|
5183
5252
|
}
|
|
5184
5253
|
return true;
|
|
@@ -8057,10 +8126,10 @@ function toQueryTarget(serializer, target) {
|
|
|
8057
8126
|
result.structuredQuery.limit = limit;
|
|
8058
8127
|
}
|
|
8059
8128
|
if (target.startAt) {
|
|
8060
|
-
result.structuredQuery.startAt =
|
|
8129
|
+
result.structuredQuery.startAt = toStartAtCursor(target.startAt);
|
|
8061
8130
|
}
|
|
8062
8131
|
if (target.endAt) {
|
|
8063
|
-
result.structuredQuery.endAt =
|
|
8132
|
+
result.structuredQuery.endAt = toEndAtCursor(target.endAt);
|
|
8064
8133
|
}
|
|
8065
8134
|
return result;
|
|
8066
8135
|
}
|
|
@@ -8093,11 +8162,11 @@ function convertQueryTargetToQuery(target) {
|
|
|
8093
8162
|
}
|
|
8094
8163
|
let startAt = null;
|
|
8095
8164
|
if (query.startAt) {
|
|
8096
|
-
startAt =
|
|
8165
|
+
startAt = fromStartAtCursor(query.startAt);
|
|
8097
8166
|
}
|
|
8098
8167
|
let endAt = null;
|
|
8099
8168
|
if (query.endAt) {
|
|
8100
|
-
endAt =
|
|
8169
|
+
endAt = fromEndAtCursor(query.endAt);
|
|
8101
8170
|
}
|
|
8102
8171
|
return newQuery(path, collectionGroup, orderBy, filterBy, limit, "F" /* First */, startAt, endAt);
|
|
8103
8172
|
}
|
|
@@ -8188,16 +8257,27 @@ function toOrder(orderBys) {
|
|
|
8188
8257
|
function fromOrder(orderBys) {
|
|
8189
8258
|
return orderBys.map(order => fromPropertyOrder(order));
|
|
8190
8259
|
}
|
|
8191
|
-
function
|
|
8260
|
+
function toStartAtCursor(cursor) {
|
|
8192
8261
|
return {
|
|
8193
|
-
before: cursor.
|
|
8262
|
+
before: cursor.inclusive,
|
|
8194
8263
|
values: cursor.position
|
|
8195
8264
|
};
|
|
8196
8265
|
}
|
|
8197
|
-
function
|
|
8198
|
-
|
|
8266
|
+
function toEndAtCursor(cursor) {
|
|
8267
|
+
return {
|
|
8268
|
+
before: !cursor.inclusive,
|
|
8269
|
+
values: cursor.position
|
|
8270
|
+
};
|
|
8271
|
+
}
|
|
8272
|
+
function fromStartAtCursor(cursor) {
|
|
8273
|
+
const inclusive = !!cursor.before;
|
|
8274
|
+
const position = cursor.values || [];
|
|
8275
|
+
return new Bound(position, inclusive);
|
|
8276
|
+
}
|
|
8277
|
+
function fromEndAtCursor(cursor) {
|
|
8278
|
+
const inclusive = !cursor.before;
|
|
8199
8279
|
const position = cursor.values || [];
|
|
8200
|
-
return new Bound(position,
|
|
8280
|
+
return new Bound(position, inclusive);
|
|
8201
8281
|
}
|
|
8202
8282
|
// visible for testing
|
|
8203
8283
|
function toDirection(dir) {
|
|
@@ -8661,6 +8741,19 @@ function fromBundleMetadata(metadata) {
|
|
|
8661
8741
|
version: metadata.version,
|
|
8662
8742
|
createTime: fromVersion(metadata.createTime)
|
|
8663
8743
|
};
|
|
8744
|
+
}
|
|
8745
|
+
function toDbIndexConfiguration(index) {
|
|
8746
|
+
return new DbIndexConfiguration(index.indexId, index.collectionGroup, index.fields.map(s => [s.fieldPath.canonicalString(), s.kind]));
|
|
8747
|
+
}
|
|
8748
|
+
function fromDbIndexConfiguration(index, state) {
|
|
8749
|
+
const decodedState = state
|
|
8750
|
+
? new IndexState(state.sequenceNumber, new IndexOffset(fromDbTimestamp(state.readTime), new DocumentKey(decodeResourcePath(state.documentKey)), state.largestBatchId))
|
|
8751
|
+
: IndexState.empty();
|
|
8752
|
+
const decodedSegments = index.fields.map(([fieldPath, kind]) => new IndexSegment(FieldPath$1.fromServerFormat(fieldPath), kind));
|
|
8753
|
+
return new FieldIndex(index.indexId, index.collectionGroup, decodedSegments, decodedState);
|
|
8754
|
+
}
|
|
8755
|
+
function toDbIndexState(indexId, user, sequenceNumber, offset) {
|
|
8756
|
+
return new DbIndexState(indexId, user.uid || '', sequenceNumber, toDbTimestamp(offset.readTime), encodeResourcePath(offset.documentKey.path), offset.largestBatchId);
|
|
8664
8757
|
}
|
|
8665
8758
|
|
|
8666
8759
|
/**
|
|
@@ -8750,6 +8843,38 @@ class MemoryIndexManager {
|
|
|
8750
8843
|
getCollectionParents(transaction, collectionId) {
|
|
8751
8844
|
return PersistencePromise.resolve(this.collectionParentIndex.getEntries(collectionId));
|
|
8752
8845
|
}
|
|
8846
|
+
addFieldIndex(transaction, index) {
|
|
8847
|
+
// Field indices are not supported with memory persistence.
|
|
8848
|
+
return PersistencePromise.resolve();
|
|
8849
|
+
}
|
|
8850
|
+
deleteFieldIndex(transaction, index) {
|
|
8851
|
+
// Field indices are not supported with memory persistence.
|
|
8852
|
+
return PersistencePromise.resolve();
|
|
8853
|
+
}
|
|
8854
|
+
getDocumentsMatchingTarget(transaction, fieldIndex, target) {
|
|
8855
|
+
// Field indices are not supported with memory persistence.
|
|
8856
|
+
return PersistencePromise.resolve(documentKeySet());
|
|
8857
|
+
}
|
|
8858
|
+
getFieldIndex(transaction, target) {
|
|
8859
|
+
// Field indices are not supported with memory persistence.
|
|
8860
|
+
return PersistencePromise.resolve(null);
|
|
8861
|
+
}
|
|
8862
|
+
getFieldIndexes(transaction, collectionGroup) {
|
|
8863
|
+
// Field indices are not supported with memory persistence.
|
|
8864
|
+
return PersistencePromise.resolve([]);
|
|
8865
|
+
}
|
|
8866
|
+
getNextCollectionGroupToUpdate(transaction) {
|
|
8867
|
+
// Field indices are not supported with memory persistence.
|
|
8868
|
+
return PersistencePromise.resolve(null);
|
|
8869
|
+
}
|
|
8870
|
+
updateCollectionGroup(transaction, collectionGroup, offset) {
|
|
8871
|
+
// Field indices are not supported with memory persistence.
|
|
8872
|
+
return PersistencePromise.resolve();
|
|
8873
|
+
}
|
|
8874
|
+
updateIndexEntries(transaction, documents) {
|
|
8875
|
+
// Field indices are not supported with memory persistence.
|
|
8876
|
+
return PersistencePromise.resolve();
|
|
8877
|
+
}
|
|
8753
8878
|
}
|
|
8754
8879
|
/**
|
|
8755
8880
|
* Internal implementation of the collection-parent index exposed by MemoryIndexManager.
|
|
@@ -8801,17 +8926,22 @@ class MemoryCollectionParentIndex {
|
|
|
8801
8926
|
*/
|
|
8802
8927
|
/**
|
|
8803
8928
|
* A persisted implementation of IndexManager.
|
|
8929
|
+
*
|
|
8930
|
+
* PORTING NOTE: Unlike iOS and Android, the Web SDK does not memoize index
|
|
8931
|
+
* data as it supports multi-tab access.
|
|
8804
8932
|
*/
|
|
8805
8933
|
class IndexedDbIndexManager {
|
|
8806
|
-
constructor() {
|
|
8934
|
+
constructor(user) {
|
|
8935
|
+
this.user = user;
|
|
8807
8936
|
/**
|
|
8808
8937
|
* An in-memory copy of the index entries we've already written since the SDK
|
|
8809
8938
|
* launched. Used to avoid re-writing the same entry repeatedly.
|
|
8810
8939
|
*
|
|
8811
|
-
* This is *NOT* a complete cache of what's in persistence and so can never be
|
|
8812
|
-
* satisfy reads.
|
|
8940
|
+
* This is *NOT* a complete cache of what's in persistence and so can never be
|
|
8941
|
+
* used to satisfy reads.
|
|
8813
8942
|
*/
|
|
8814
8943
|
this.collectionParentsCache = new MemoryCollectionParentIndex();
|
|
8944
|
+
this.uid = user.uid || '';
|
|
8815
8945
|
}
|
|
8816
8946
|
/**
|
|
8817
8947
|
* Adds a new entry to the collection parent index.
|
|
@@ -8858,6 +8988,85 @@ class IndexedDbIndexManager {
|
|
|
8858
8988
|
return parentPaths;
|
|
8859
8989
|
});
|
|
8860
8990
|
}
|
|
8991
|
+
addFieldIndex(transaction, index) {
|
|
8992
|
+
// TODO(indexing): Verify that the auto-incrementing index ID works in
|
|
8993
|
+
// Safari & Firefox.
|
|
8994
|
+
const indexes = indexConfigurationStore(transaction);
|
|
8995
|
+
const dbIndex = toDbIndexConfiguration(index);
|
|
8996
|
+
delete dbIndex.indexId; // `indexId` is auto-populated by IndexedDb
|
|
8997
|
+
return indexes.add(dbIndex).next();
|
|
8998
|
+
}
|
|
8999
|
+
deleteFieldIndex(transaction, index) {
|
|
9000
|
+
const indexes = indexConfigurationStore(transaction);
|
|
9001
|
+
const states = indexStateStore(transaction);
|
|
9002
|
+
const entries = indexEntriesStore(transaction);
|
|
9003
|
+
return indexes
|
|
9004
|
+
.delete(index.indexId)
|
|
9005
|
+
.next(() => states.delete(IDBKeyRange.bound([index.indexId], [index.indexId + 1],
|
|
9006
|
+
/*lowerOpen=*/ false,
|
|
9007
|
+
/*upperOpen=*/ true)))
|
|
9008
|
+
.next(() => entries.delete(IDBKeyRange.bound([index.indexId], [index.indexId + 1],
|
|
9009
|
+
/*lowerOpen=*/ false,
|
|
9010
|
+
/*upperOpen=*/ true)));
|
|
9011
|
+
}
|
|
9012
|
+
getDocumentsMatchingTarget(transaction, fieldIndex, target) {
|
|
9013
|
+
// TODO(indexing): Implement
|
|
9014
|
+
return PersistencePromise.resolve(documentKeySet());
|
|
9015
|
+
}
|
|
9016
|
+
getFieldIndex(transaction, target) {
|
|
9017
|
+
// TODO(indexing): Implement
|
|
9018
|
+
return PersistencePromise.resolve(null);
|
|
9019
|
+
}
|
|
9020
|
+
getFieldIndexes(transaction, collectionGroup) {
|
|
9021
|
+
const indexes = indexConfigurationStore(transaction);
|
|
9022
|
+
const states = indexStateStore(transaction);
|
|
9023
|
+
return (collectionGroup
|
|
9024
|
+
? indexes.loadAll(DbIndexConfiguration.collectionGroupIndex, IDBKeyRange.bound(collectionGroup, collectionGroup))
|
|
9025
|
+
: indexes.loadAll()).next(indexConfigs => {
|
|
9026
|
+
const result = [];
|
|
9027
|
+
return PersistencePromise.forEach(indexConfigs, (indexConfig) => {
|
|
9028
|
+
return states
|
|
9029
|
+
.get([indexConfig.indexId, this.uid])
|
|
9030
|
+
.next(indexState => {
|
|
9031
|
+
result.push(fromDbIndexConfiguration(indexConfig, indexState));
|
|
9032
|
+
});
|
|
9033
|
+
}).next(() => result);
|
|
9034
|
+
});
|
|
9035
|
+
}
|
|
9036
|
+
getNextCollectionGroupToUpdate(transaction) {
|
|
9037
|
+
return this.getFieldIndexes(transaction).next(indexes => {
|
|
9038
|
+
if (indexes.length === 0) {
|
|
9039
|
+
return null;
|
|
9040
|
+
}
|
|
9041
|
+
indexes.sort((l, r) => l.indexState.sequenceNumber - r.indexState.sequenceNumber);
|
|
9042
|
+
return indexes[0].collectionGroup;
|
|
9043
|
+
});
|
|
9044
|
+
}
|
|
9045
|
+
updateCollectionGroup(transaction, collectionGroup, offset) {
|
|
9046
|
+
const indexes = indexConfigurationStore(transaction);
|
|
9047
|
+
const states = indexStateStore(transaction);
|
|
9048
|
+
return this.getNextSequenceNumber(transaction).next(nextSequenceNumber => indexes
|
|
9049
|
+
.loadAll(DbIndexConfiguration.collectionGroupIndex, IDBKeyRange.bound(collectionGroup, collectionGroup))
|
|
9050
|
+
.next(configs => PersistencePromise.forEach(configs, (config) => states.put(toDbIndexState(config.indexId, this.user, nextSequenceNumber, offset)))));
|
|
9051
|
+
}
|
|
9052
|
+
updateIndexEntries(transaction, documents) {
|
|
9053
|
+
// TODO(indexing): Implement
|
|
9054
|
+
return PersistencePromise.resolve();
|
|
9055
|
+
}
|
|
9056
|
+
getNextSequenceNumber(transaction) {
|
|
9057
|
+
let nextSequenceNumber = 1;
|
|
9058
|
+
const states = indexStateStore(transaction);
|
|
9059
|
+
return states
|
|
9060
|
+
.iterate({
|
|
9061
|
+
index: DbIndexState.sequenceNumberIndex,
|
|
9062
|
+
reverse: true,
|
|
9063
|
+
range: IDBKeyRange.upperBound([this.uid, Number.MAX_SAFE_INTEGER])
|
|
9064
|
+
}, (_, state, controller) => {
|
|
9065
|
+
controller.done();
|
|
9066
|
+
nextSequenceNumber = state.sequenceNumber + 1;
|
|
9067
|
+
})
|
|
9068
|
+
.next(() => nextSequenceNumber);
|
|
9069
|
+
}
|
|
8861
9070
|
}
|
|
8862
9071
|
/**
|
|
8863
9072
|
* Helper to get a typed SimpleDbStore for the collectionParents
|
|
@@ -8865,6 +9074,24 @@ class IndexedDbIndexManager {
|
|
|
8865
9074
|
*/
|
|
8866
9075
|
function collectionParentsStore(txn) {
|
|
8867
9076
|
return getStore(txn, DbCollectionParent.store);
|
|
9077
|
+
}
|
|
9078
|
+
/**
|
|
9079
|
+
* Helper to get a typed SimpleDbStore for the index entry object store.
|
|
9080
|
+
*/
|
|
9081
|
+
function indexEntriesStore(txn) {
|
|
9082
|
+
return getStore(txn, DbIndexEntry.store);
|
|
9083
|
+
}
|
|
9084
|
+
/**
|
|
9085
|
+
* Helper to get a typed SimpleDbStore for the index configuration object store.
|
|
9086
|
+
*/
|
|
9087
|
+
function indexConfigurationStore(txn) {
|
|
9088
|
+
return getStore(txn, DbIndexConfiguration.store);
|
|
9089
|
+
}
|
|
9090
|
+
/**
|
|
9091
|
+
* Helper to get a typed SimpleDbStore for the index state object store.
|
|
9092
|
+
*/
|
|
9093
|
+
function indexStateStore(txn) {
|
|
9094
|
+
return getStore(txn, DbIndexState.store);
|
|
8868
9095
|
}
|
|
8869
9096
|
|
|
8870
9097
|
/**
|
|
@@ -10334,12 +10561,10 @@ class RemoteDocumentChangeBuffer {
|
|
|
10334
10561
|
* `newIndexedDbRemoteDocumentCache()`.
|
|
10335
10562
|
*/
|
|
10336
10563
|
class IndexedDbRemoteDocumentCacheImpl {
|
|
10337
|
-
|
|
10338
|
-
* @param serializer - The document serializer.
|
|
10339
|
-
* @param indexManager - The query indexes that need to be maintained.
|
|
10340
|
-
*/
|
|
10341
|
-
constructor(serializer, indexManager) {
|
|
10564
|
+
constructor(serializer) {
|
|
10342
10565
|
this.serializer = serializer;
|
|
10566
|
+
}
|
|
10567
|
+
setIndexManager(indexManager) {
|
|
10343
10568
|
this.indexManager = indexManager;
|
|
10344
10569
|
}
|
|
10345
10570
|
/**
|
|
@@ -10461,21 +10686,21 @@ class IndexedDbRemoteDocumentCacheImpl {
|
|
|
10461
10686
|
}
|
|
10462
10687
|
});
|
|
10463
10688
|
}
|
|
10464
|
-
|
|
10689
|
+
getAll(transaction, collection, sinceReadTime) {
|
|
10465
10690
|
let results = mutableDocumentMap();
|
|
10466
|
-
const immediateChildrenPathLength =
|
|
10691
|
+
const immediateChildrenPathLength = collection.length + 1;
|
|
10467
10692
|
const iterationOptions = {};
|
|
10468
10693
|
if (sinceReadTime.isEqual(SnapshotVersion.min())) {
|
|
10469
10694
|
// Documents are ordered by key, so we can use a prefix scan to narrow
|
|
10470
10695
|
// down the documents we need to match the query against.
|
|
10471
|
-
const startKey =
|
|
10696
|
+
const startKey = collection.toArray();
|
|
10472
10697
|
iterationOptions.range = IDBKeyRange.lowerBound(startKey);
|
|
10473
10698
|
}
|
|
10474
10699
|
else {
|
|
10475
10700
|
// Execute an index-free query and filter by read time. This is safe
|
|
10476
10701
|
// since all document changes to queries that have a
|
|
10477
10702
|
// lastLimboFreeSnapshotVersion (`sinceReadTime`) have a read time set.
|
|
10478
|
-
const collectionKey =
|
|
10703
|
+
const collectionKey = collection.toArray();
|
|
10479
10704
|
const readTimeKey = toDbTimestampKey(sinceReadTime);
|
|
10480
10705
|
iterationOptions.range = IDBKeyRange.lowerBound([collectionKey, readTimeKey],
|
|
10481
10706
|
/* open= */ true);
|
|
@@ -10492,12 +10717,12 @@ class IndexedDbRemoteDocumentCacheImpl {
|
|
|
10492
10717
|
return;
|
|
10493
10718
|
}
|
|
10494
10719
|
const document = this.maybeDecodeDocument(DocumentKey.fromSegments(key), dbRemoteDoc);
|
|
10495
|
-
if (
|
|
10496
|
-
control.done();
|
|
10497
|
-
}
|
|
10498
|
-
else if (queryMatches(query, document)) {
|
|
10720
|
+
if (collection.isPrefixOf(document.key.path)) {
|
|
10499
10721
|
results = results.insert(document.key, document);
|
|
10500
10722
|
}
|
|
10723
|
+
else {
|
|
10724
|
+
control.done();
|
|
10725
|
+
}
|
|
10501
10726
|
})
|
|
10502
10727
|
.next(() => results);
|
|
10503
10728
|
}
|
|
@@ -10535,14 +10760,9 @@ class IndexedDbRemoteDocumentCacheImpl {
|
|
|
10535
10760
|
return MutableDocument.newInvalidDocument(documentKey);
|
|
10536
10761
|
}
|
|
10537
10762
|
}
|
|
10538
|
-
/**
|
|
10539
|
-
|
|
10540
|
-
|
|
10541
|
-
* @param serializer - The document serializer.
|
|
10542
|
-
* @param indexManager - The query indexes that need to be maintained.
|
|
10543
|
-
*/
|
|
10544
|
-
function newIndexedDbRemoteDocumentCache(serializer, indexManager) {
|
|
10545
|
-
return new IndexedDbRemoteDocumentCacheImpl(serializer, indexManager);
|
|
10763
|
+
/** Creates a new IndexedDbRemoteDocumentCache. */
|
|
10764
|
+
function newIndexedDbRemoteDocumentCache(serializer) {
|
|
10765
|
+
return new IndexedDbRemoteDocumentCacheImpl(serializer);
|
|
10546
10766
|
}
|
|
10547
10767
|
/**
|
|
10548
10768
|
* Returns the set of documents that have changed since the specified read
|
|
@@ -10988,14 +11208,17 @@ function createNamedQueriesStore(db) {
|
|
|
10988
11208
|
});
|
|
10989
11209
|
}
|
|
10990
11210
|
function createFieldIndex(db) {
|
|
10991
|
-
db.createObjectStore(DbIndexConfiguration.store, {
|
|
10992
|
-
keyPath: DbIndexConfiguration.keyPath
|
|
11211
|
+
const indexConfiguratioStore = db.createObjectStore(DbIndexConfiguration.store, {
|
|
11212
|
+
keyPath: DbIndexConfiguration.keyPath,
|
|
11213
|
+
autoIncrement: true
|
|
10993
11214
|
});
|
|
10994
|
-
|
|
11215
|
+
indexConfiguratioStore.createIndex(DbIndexConfiguration.collectionGroupIndex, DbIndexConfiguration.collectionGroupIndexPath, { unique: false });
|
|
11216
|
+
const indexStateStore = db.createObjectStore(DbIndexState.store, {
|
|
10995
11217
|
keyPath: DbIndexState.keyPath
|
|
10996
11218
|
});
|
|
10997
|
-
|
|
10998
|
-
|
|
11219
|
+
indexStateStore.createIndex(DbIndexState.sequenceNumberIndex, DbIndexState.sequenceNumberIndexPath, { unique: false });
|
|
11220
|
+
db.createObjectStore(DbIndexEntry.store, {
|
|
11221
|
+
keyPath: DbIndexEntry.keyPath
|
|
10999
11222
|
});
|
|
11000
11223
|
}
|
|
11001
11224
|
|
|
@@ -11108,7 +11331,7 @@ class IndexedDbPersistence {
|
|
|
11108
11331
|
* If set to true, forcefully obtains database access. Existing tabs will
|
|
11109
11332
|
* no longer be able to access IndexedDB.
|
|
11110
11333
|
*/
|
|
11111
|
-
forceOwningTab) {
|
|
11334
|
+
forceOwningTab, schemaVersion = SCHEMA_VERSION) {
|
|
11112
11335
|
this.allowTabSynchronization = allowTabSynchronization;
|
|
11113
11336
|
this.persistenceKey = persistenceKey;
|
|
11114
11337
|
this.clientId = clientId;
|
|
@@ -11117,6 +11340,7 @@ class IndexedDbPersistence {
|
|
|
11117
11340
|
this.document = document;
|
|
11118
11341
|
this.sequenceNumberSyncer = sequenceNumberSyncer;
|
|
11119
11342
|
this.forceOwningTab = forceOwningTab;
|
|
11343
|
+
this.schemaVersion = schemaVersion;
|
|
11120
11344
|
this.listenSequence = null;
|
|
11121
11345
|
this._started = false;
|
|
11122
11346
|
this.isPrimary = false;
|
|
@@ -11138,10 +11362,9 @@ class IndexedDbPersistence {
|
|
|
11138
11362
|
this.referenceDelegate = new IndexedDbLruDelegateImpl(this, lruParams);
|
|
11139
11363
|
this.dbName = persistenceKey + MAIN_DATABASE;
|
|
11140
11364
|
this.serializer = new LocalSerializer(serializer);
|
|
11141
|
-
this.simpleDb = new SimpleDb(this.dbName,
|
|
11365
|
+
this.simpleDb = new SimpleDb(this.dbName, this.schemaVersion, new SchemaConverter(this.serializer));
|
|
11142
11366
|
this.targetCache = new IndexedDbTargetCache(this.referenceDelegate, this.serializer);
|
|
11143
|
-
this.
|
|
11144
|
-
this.remoteDocumentCache = newIndexedDbRemoteDocumentCache(this.serializer, this.indexManager);
|
|
11367
|
+
this.remoteDocumentCache = newIndexedDbRemoteDocumentCache(this.serializer);
|
|
11145
11368
|
this.bundleCache = new IndexedDbBundleCache();
|
|
11146
11369
|
if (this.window && this.window.localStorage) {
|
|
11147
11370
|
this.webStorage = this.window.localStorage;
|
|
@@ -11477,8 +11700,8 @@ class IndexedDbPersistence {
|
|
|
11477
11700
|
get started() {
|
|
11478
11701
|
return this._started;
|
|
11479
11702
|
}
|
|
11480
|
-
getMutationQueue(user) {
|
|
11481
|
-
return IndexedDbMutationQueue.forUser(user, this.serializer,
|
|
11703
|
+
getMutationQueue(user, indexManager) {
|
|
11704
|
+
return IndexedDbMutationQueue.forUser(user, this.serializer, indexManager, this.referenceDelegate);
|
|
11482
11705
|
}
|
|
11483
11706
|
getTargetCache() {
|
|
11484
11707
|
return this.targetCache;
|
|
@@ -11486,8 +11709,8 @@ class IndexedDbPersistence {
|
|
|
11486
11709
|
getRemoteDocumentCache() {
|
|
11487
11710
|
return this.remoteDocumentCache;
|
|
11488
11711
|
}
|
|
11489
|
-
getIndexManager() {
|
|
11490
|
-
return
|
|
11712
|
+
getIndexManager(user) {
|
|
11713
|
+
return new IndexedDbIndexManager(user);
|
|
11491
11714
|
}
|
|
11492
11715
|
getBundleCache() {
|
|
11493
11716
|
return this.bundleCache;
|
|
@@ -11495,11 +11718,12 @@ class IndexedDbPersistence {
|
|
|
11495
11718
|
runTransaction(action, mode, transactionOperation) {
|
|
11496
11719
|
logDebug(LOG_TAG$d, 'Starting transaction:', action);
|
|
11497
11720
|
const simpleDbMode = mode === 'readonly' ? 'readonly' : 'readwrite';
|
|
11721
|
+
const objectStores = getObjectStores(this.schemaVersion);
|
|
11498
11722
|
let persistenceTransaction;
|
|
11499
11723
|
// Do all transactions as readwrite against all object stores, since we
|
|
11500
11724
|
// are the only reader/writer.
|
|
11501
11725
|
return this.simpleDb
|
|
11502
|
-
.runTransaction(action, simpleDbMode,
|
|
11726
|
+
.runTransaction(action, simpleDbMode, objectStores, simpleDbTxn => {
|
|
11503
11727
|
persistenceTransaction = new IndexedDbTransaction(simpleDbTxn, this.listenSequence
|
|
11504
11728
|
? this.listenSequence.next()
|
|
11505
11729
|
: ListenSequence.INVALID);
|
|
@@ -11871,39 +12095,28 @@ class LocalDocumentsView {
|
|
|
11871
12095
|
getDocumentsMatchingCollectionQuery(transaction, query, sinceReadTime) {
|
|
11872
12096
|
// Query the remote documents and overlay mutations.
|
|
11873
12097
|
let results;
|
|
11874
|
-
let mutationBatches;
|
|
11875
12098
|
return this.remoteDocumentCache
|
|
11876
|
-
.
|
|
12099
|
+
.getAll(transaction, query.path, sinceReadTime)
|
|
11877
12100
|
.next(queryResults => {
|
|
11878
12101
|
results = queryResults;
|
|
11879
12102
|
return this.mutationQueue.getAllMutationBatchesAffectingQuery(transaction, query);
|
|
11880
12103
|
})
|
|
11881
|
-
.next(
|
|
11882
|
-
mutationBatches
|
|
11883
|
-
|
|
11884
|
-
|
|
11885
|
-
|
|
11886
|
-
|
|
11887
|
-
|
|
11888
|
-
|
|
11889
|
-
|
|
11890
|
-
|
|
11891
|
-
|
|
11892
|
-
|
|
11893
|
-
|
|
11894
|
-
let document = results.get(key);
|
|
11895
|
-
if (document == null) {
|
|
11896
|
-
// Create invalid document to apply mutations on top of
|
|
11897
|
-
document = MutableDocument.newInvalidDocument(key);
|
|
11898
|
-
results = results.insert(key, document);
|
|
11899
|
-
}
|
|
11900
|
-
mutationApplyToLocalView(mutation, document, batch.localWriteTime);
|
|
11901
|
-
if (!document.isFoundDocument()) {
|
|
11902
|
-
results = results.remove(key);
|
|
11903
|
-
}
|
|
12104
|
+
.next(mutationBatches => {
|
|
12105
|
+
for (const batch of mutationBatches) {
|
|
12106
|
+
for (const mutation of batch.mutations) {
|
|
12107
|
+
const key = mutation.key;
|
|
12108
|
+
let document = results.get(key);
|
|
12109
|
+
if (document == null) {
|
|
12110
|
+
// Create invalid document to apply mutations on top of
|
|
12111
|
+
document = MutableDocument.newInvalidDocument(key);
|
|
12112
|
+
results = results.insert(key, document);
|
|
12113
|
+
}
|
|
12114
|
+
mutationApplyToLocalView(mutation, document, batch.localWriteTime);
|
|
12115
|
+
if (!document.isFoundDocument()) {
|
|
12116
|
+
results = results.remove(key);
|
|
11904
12117
|
}
|
|
11905
12118
|
}
|
|
11906
|
-
}
|
|
12119
|
+
}
|
|
11907
12120
|
})
|
|
11908
12121
|
.next(() => {
|
|
11909
12122
|
// Finally, filter out any documents that don't actually match
|
|
@@ -11916,29 +12129,6 @@ class LocalDocumentsView {
|
|
|
11916
12129
|
return results;
|
|
11917
12130
|
});
|
|
11918
12131
|
}
|
|
11919
|
-
addMissingBaseDocuments(transaction, matchingMutationBatches, existingDocuments) {
|
|
11920
|
-
let missingBaseDocEntriesForPatching = documentKeySet();
|
|
11921
|
-
for (const batch of matchingMutationBatches) {
|
|
11922
|
-
for (const mutation of batch.mutations) {
|
|
11923
|
-
if (mutation instanceof PatchMutation &&
|
|
11924
|
-
existingDocuments.get(mutation.key) === null) {
|
|
11925
|
-
missingBaseDocEntriesForPatching =
|
|
11926
|
-
missingBaseDocEntriesForPatching.add(mutation.key);
|
|
11927
|
-
}
|
|
11928
|
-
}
|
|
11929
|
-
}
|
|
11930
|
-
let mergedDocuments = existingDocuments;
|
|
11931
|
-
return this.remoteDocumentCache
|
|
11932
|
-
.getEntries(transaction, missingBaseDocEntriesForPatching)
|
|
11933
|
-
.next(missingBaseDocs => {
|
|
11934
|
-
missingBaseDocs.forEach((key, doc) => {
|
|
11935
|
-
if (doc.isFoundDocument()) {
|
|
11936
|
-
mergedDocuments = mergedDocuments.insert(key, doc);
|
|
11937
|
-
}
|
|
11938
|
-
});
|
|
11939
|
-
return mergedDocuments;
|
|
11940
|
-
});
|
|
11941
|
-
}
|
|
11942
12132
|
}
|
|
11943
12133
|
|
|
11944
12134
|
/**
|
|
@@ -11997,11 +12187,18 @@ class LocalStoreImpl {
|
|
|
11997
12187
|
* PORTING NOTE: This is only used for multi-tab synchronization.
|
|
11998
12188
|
*/
|
|
11999
12189
|
this.lastDocumentChangeReadTime = SnapshotVersion.min();
|
|
12000
|
-
this.mutationQueue = persistence.getMutationQueue(initialUser);
|
|
12001
12190
|
this.remoteDocuments = persistence.getRemoteDocumentCache();
|
|
12002
12191
|
this.targetCache = persistence.getTargetCache();
|
|
12003
|
-
this.localDocuments = new LocalDocumentsView(this.remoteDocuments, this.mutationQueue, this.persistence.getIndexManager());
|
|
12004
12192
|
this.bundleCache = persistence.getBundleCache();
|
|
12193
|
+
this.initializeUserComponents(initialUser);
|
|
12194
|
+
}
|
|
12195
|
+
initializeUserComponents(user) {
|
|
12196
|
+
// TODO(indexing): Add spec tests that test these components change after a
|
|
12197
|
+
// user change
|
|
12198
|
+
this.indexManager = this.persistence.getIndexManager(user);
|
|
12199
|
+
this.mutationQueue = this.persistence.getMutationQueue(user, this.indexManager);
|
|
12200
|
+
this.localDocuments = new LocalDocumentsView(this.remoteDocuments, this.mutationQueue, this.indexManager);
|
|
12201
|
+
this.remoteDocuments.setIndexManager(this.indexManager);
|
|
12005
12202
|
this.queryEngine.setLocalDocumentsView(this.localDocuments);
|
|
12006
12203
|
}
|
|
12007
12204
|
collectGarbage(garbageCollector) {
|
|
@@ -12023,8 +12220,6 @@ persistence, queryEngine, initialUser, serializer) {
|
|
|
12023
12220
|
// change.
|
|
12024
12221
|
async function localStoreHandleUserChange(localStore, user) {
|
|
12025
12222
|
const localStoreImpl = debugCast(localStore);
|
|
12026
|
-
let newMutationQueue = localStoreImpl.mutationQueue;
|
|
12027
|
-
let newLocalDocuments = localStoreImpl.localDocuments;
|
|
12028
12223
|
const result = await localStoreImpl.persistence.runTransaction('Handle user change', 'readonly', txn => {
|
|
12029
12224
|
// Swap out the mutation queue, grabbing the pending mutation batches
|
|
12030
12225
|
// before and after.
|
|
@@ -12033,11 +12228,8 @@ async function localStoreHandleUserChange(localStore, user) {
|
|
|
12033
12228
|
.getAllMutationBatches(txn)
|
|
12034
12229
|
.next(promisedOldBatches => {
|
|
12035
12230
|
oldBatches = promisedOldBatches;
|
|
12036
|
-
|
|
12037
|
-
|
|
12038
|
-
// MutationQueue.
|
|
12039
|
-
newLocalDocuments = new LocalDocumentsView(localStoreImpl.remoteDocuments, newMutationQueue, localStoreImpl.persistence.getIndexManager());
|
|
12040
|
-
return newMutationQueue.getAllMutationBatches(txn);
|
|
12231
|
+
localStoreImpl.initializeUserComponents(user);
|
|
12232
|
+
return localStoreImpl.mutationQueue.getAllMutationBatches(txn);
|
|
12041
12233
|
})
|
|
12042
12234
|
.next(newBatches => {
|
|
12043
12235
|
const removedBatchIds = [];
|
|
@@ -12058,7 +12250,7 @@ async function localStoreHandleUserChange(localStore, user) {
|
|
|
12058
12250
|
}
|
|
12059
12251
|
// Return the set of all (potentially) changed documents and the list
|
|
12060
12252
|
// of mutation batch IDs that were affected by change.
|
|
12061
|
-
return
|
|
12253
|
+
return localStoreImpl.localDocuments
|
|
12062
12254
|
.getDocuments(txn, changedKeys)
|
|
12063
12255
|
.next(affectedDocuments => {
|
|
12064
12256
|
return {
|
|
@@ -12069,9 +12261,6 @@ async function localStoreHandleUserChange(localStore, user) {
|
|
|
12069
12261
|
});
|
|
12070
12262
|
});
|
|
12071
12263
|
});
|
|
12072
|
-
localStoreImpl.mutationQueue = newMutationQueue;
|
|
12073
|
-
localStoreImpl.localDocuments = newLocalDocuments;
|
|
12074
|
-
localStoreImpl.queryEngine.setLocalDocumentsView(localStoreImpl.localDocuments);
|
|
12075
12264
|
return result;
|
|
12076
12265
|
}
|
|
12077
12266
|
/* Accepts locally generated Mutations and commit them to storage. */
|
|
@@ -13137,14 +13326,16 @@ class MemoryRemoteDocumentCacheImpl {
|
|
|
13137
13326
|
* expected to just return 0 to avoid unnecessarily doing the work of
|
|
13138
13327
|
* calculating the size.
|
|
13139
13328
|
*/
|
|
13140
|
-
constructor(
|
|
13141
|
-
this.indexManager = indexManager;
|
|
13329
|
+
constructor(sizer) {
|
|
13142
13330
|
this.sizer = sizer;
|
|
13143
13331
|
/** Underlying cache of documents and their read times. */
|
|
13144
13332
|
this.docs = documentEntryMap();
|
|
13145
13333
|
/** Size of all cached documents. */
|
|
13146
13334
|
this.size = 0;
|
|
13147
13335
|
}
|
|
13336
|
+
setIndexManager(indexManager) {
|
|
13337
|
+
this.indexManager = indexManager;
|
|
13338
|
+
}
|
|
13148
13339
|
/**
|
|
13149
13340
|
* Adds the supplied entry to the cache and updates the cache size as appropriate.
|
|
13150
13341
|
*
|
|
@@ -13192,21 +13383,22 @@ class MemoryRemoteDocumentCacheImpl {
|
|
|
13192
13383
|
});
|
|
13193
13384
|
return PersistencePromise.resolve(results);
|
|
13194
13385
|
}
|
|
13195
|
-
|
|
13386
|
+
getAll(transaction, collectionPath, sinceReadTime) {
|
|
13196
13387
|
let results = mutableDocumentMap();
|
|
13197
13388
|
// Documents are ordered by key, so we can use a prefix scan to narrow down
|
|
13198
13389
|
// the documents we need to match the query against.
|
|
13199
|
-
const prefix = new DocumentKey(
|
|
13390
|
+
const prefix = new DocumentKey(collectionPath.child(''));
|
|
13200
13391
|
const iterator = this.docs.getIteratorFrom(prefix);
|
|
13201
13392
|
while (iterator.hasNext()) {
|
|
13202
13393
|
const { key, value: { document } } = iterator.getNext();
|
|
13203
|
-
if (!
|
|
13394
|
+
if (!collectionPath.isPrefixOf(key.path)) {
|
|
13204
13395
|
break;
|
|
13205
13396
|
}
|
|
13206
|
-
if (
|
|
13397
|
+
if (key.path.length > collectionPath.length + 1) {
|
|
13398
|
+
// Exclude entries from subcollections.
|
|
13207
13399
|
continue;
|
|
13208
13400
|
}
|
|
13209
|
-
if (
|
|
13401
|
+
if (document.readTime.compareTo(sinceReadTime) <= 0) {
|
|
13210
13402
|
continue;
|
|
13211
13403
|
}
|
|
13212
13404
|
results = results.insert(document.key, document.mutableCopy());
|
|
@@ -13228,13 +13420,12 @@ class MemoryRemoteDocumentCacheImpl {
|
|
|
13228
13420
|
/**
|
|
13229
13421
|
* Creates a new memory-only RemoteDocumentCache.
|
|
13230
13422
|
*
|
|
13231
|
-
* @param indexManager - A class that manages collection group indices.
|
|
13232
13423
|
* @param sizer - Used to assess the size of a document. For eager GC, this is
|
|
13233
13424
|
* expected to just return 0 to avoid unnecessarily doing the work of
|
|
13234
13425
|
* calculating the size.
|
|
13235
13426
|
*/
|
|
13236
|
-
function newMemoryRemoteDocumentCache(
|
|
13237
|
-
return new MemoryRemoteDocumentCacheImpl(
|
|
13427
|
+
function newMemoryRemoteDocumentCache(sizer) {
|
|
13428
|
+
return new MemoryRemoteDocumentCacheImpl(sizer);
|
|
13238
13429
|
}
|
|
13239
13430
|
/**
|
|
13240
13431
|
* Handles the details of adding and updating documents in the MemoryRemoteDocumentCache.
|
|
@@ -13435,7 +13626,7 @@ class MemoryPersistence {
|
|
|
13435
13626
|
this.targetCache = new MemoryTargetCache(this);
|
|
13436
13627
|
const sizer = (doc) => this.referenceDelegate.documentSize(doc);
|
|
13437
13628
|
this.indexManager = new MemoryIndexManager();
|
|
13438
|
-
this.remoteDocumentCache = newMemoryRemoteDocumentCache(
|
|
13629
|
+
this.remoteDocumentCache = newMemoryRemoteDocumentCache(sizer);
|
|
13439
13630
|
this.serializer = new LocalSerializer(serializer);
|
|
13440
13631
|
this.bundleCache = new MemoryBundleCache(this.serializer);
|
|
13441
13632
|
}
|
|
@@ -13456,13 +13647,15 @@ class MemoryPersistence {
|
|
|
13456
13647
|
setNetworkEnabled() {
|
|
13457
13648
|
// No op.
|
|
13458
13649
|
}
|
|
13459
|
-
getIndexManager() {
|
|
13650
|
+
getIndexManager(user) {
|
|
13651
|
+
// We do not currently support indices for memory persistence, so we can
|
|
13652
|
+
// return the same shared instance of the memory index manager.
|
|
13460
13653
|
return this.indexManager;
|
|
13461
13654
|
}
|
|
13462
|
-
getMutationQueue(user) {
|
|
13655
|
+
getMutationQueue(user, indexManager) {
|
|
13463
13656
|
let queue = this.mutationQueues[user.toKey()];
|
|
13464
13657
|
if (!queue) {
|
|
13465
|
-
queue = new MemoryMutationQueue(
|
|
13658
|
+
queue = new MemoryMutationQueue(indexManager, this.referenceDelegate);
|
|
13466
13659
|
this.mutationQueues[user.toKey()] = queue;
|
|
13467
13660
|
}
|
|
13468
13661
|
return queue;
|
|
@@ -20425,12 +20618,12 @@ async function syncEngineListen(syncEngine, query) {
|
|
|
20425
20618
|
}
|
|
20426
20619
|
else {
|
|
20427
20620
|
const targetData = await localStoreAllocateTarget(syncEngineImpl.localStore, queryToTarget(query));
|
|
20428
|
-
const status = syncEngineImpl.sharedClientState.addLocalQueryTarget(targetData.targetId);
|
|
20429
|
-
targetId = targetData.targetId;
|
|
20430
|
-
viewSnapshot = await initializeViewAndComputeSnapshot(syncEngineImpl, query, targetId, status === 'current');
|
|
20431
20621
|
if (syncEngineImpl.isPrimaryClient) {
|
|
20432
20622
|
remoteStoreListen(syncEngineImpl.remoteStore, targetData);
|
|
20433
20623
|
}
|
|
20624
|
+
const status = syncEngineImpl.sharedClientState.addLocalQueryTarget(targetData.targetId);
|
|
20625
|
+
targetId = targetData.targetId;
|
|
20626
|
+
viewSnapshot = await initializeViewAndComputeSnapshot(syncEngineImpl, query, targetId, status === 'current');
|
|
20434
20627
|
}
|
|
20435
20628
|
return viewSnapshot;
|
|
20436
20629
|
}
|
|
@@ -24938,8 +25131,7 @@ class DocumentSnapshot extends DocumentSnapshot$1 {
|
|
|
24938
25131
|
this.metadata = metadata;
|
|
24939
25132
|
}
|
|
24940
25133
|
/**
|
|
24941
|
-
*
|
|
24942
|
-
* exists. True if the document exists.
|
|
25134
|
+
* Returns whether or not the data exists. True if the document exists.
|
|
24943
25135
|
*/
|
|
24944
25136
|
exists() {
|
|
24945
25137
|
return super.exists();
|
|
@@ -25313,51 +25505,53 @@ function limitToLast(limit) {
|
|
|
25313
25505
|
return new QueryLimitConstraint('limitToLast', limit, "L" /* Last */);
|
|
25314
25506
|
}
|
|
25315
25507
|
class QueryStartAtConstraint extends QueryConstraint {
|
|
25316
|
-
constructor(type, _docOrFields,
|
|
25508
|
+
constructor(type, _docOrFields, _inclusive) {
|
|
25317
25509
|
super();
|
|
25318
25510
|
this.type = type;
|
|
25319
25511
|
this._docOrFields = _docOrFields;
|
|
25320
|
-
this.
|
|
25512
|
+
this._inclusive = _inclusive;
|
|
25321
25513
|
}
|
|
25322
25514
|
_apply(query) {
|
|
25323
|
-
const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this.
|
|
25515
|
+
const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._inclusive);
|
|
25324
25516
|
return new Query(query.firestore, query.converter, queryWithStartAt(query._query, bound));
|
|
25325
25517
|
}
|
|
25326
25518
|
}
|
|
25327
25519
|
function startAt(...docOrFields) {
|
|
25328
|
-
return new QueryStartAtConstraint('startAt', docOrFields,
|
|
25520
|
+
return new QueryStartAtConstraint('startAt', docOrFields,
|
|
25521
|
+
/*inclusive=*/ true);
|
|
25329
25522
|
}
|
|
25330
25523
|
function startAfter(...docOrFields) {
|
|
25331
25524
|
return new QueryStartAtConstraint('startAfter', docOrFields,
|
|
25332
|
-
/*
|
|
25525
|
+
/*inclusive=*/ false);
|
|
25333
25526
|
}
|
|
25334
25527
|
class QueryEndAtConstraint extends QueryConstraint {
|
|
25335
|
-
constructor(type, _docOrFields,
|
|
25528
|
+
constructor(type, _docOrFields, _inclusive) {
|
|
25336
25529
|
super();
|
|
25337
25530
|
this.type = type;
|
|
25338
25531
|
this._docOrFields = _docOrFields;
|
|
25339
|
-
this.
|
|
25532
|
+
this._inclusive = _inclusive;
|
|
25340
25533
|
}
|
|
25341
25534
|
_apply(query) {
|
|
25342
|
-
const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this.
|
|
25535
|
+
const bound = newQueryBoundFromDocOrFields(query, this.type, this._docOrFields, this._inclusive);
|
|
25343
25536
|
return new Query(query.firestore, query.converter, queryWithEndAt(query._query, bound));
|
|
25344
25537
|
}
|
|
25345
25538
|
}
|
|
25346
25539
|
function endBefore(...docOrFields) {
|
|
25347
|
-
return new QueryEndAtConstraint('endBefore', docOrFields,
|
|
25540
|
+
return new QueryEndAtConstraint('endBefore', docOrFields,
|
|
25541
|
+
/*inclusive=*/ false);
|
|
25348
25542
|
}
|
|
25349
25543
|
function endAt(...docOrFields) {
|
|
25350
|
-
return new QueryEndAtConstraint('endAt', docOrFields, /*
|
|
25544
|
+
return new QueryEndAtConstraint('endAt', docOrFields, /*inclusive=*/ true);
|
|
25351
25545
|
}
|
|
25352
25546
|
/** Helper function to create a bound from a document or fields */
|
|
25353
|
-
function newQueryBoundFromDocOrFields(query, methodName, docOrFields,
|
|
25547
|
+
function newQueryBoundFromDocOrFields(query, methodName, docOrFields, inclusive) {
|
|
25354
25548
|
docOrFields[0] = getModularInstance(docOrFields[0]);
|
|
25355
25549
|
if (docOrFields[0] instanceof DocumentSnapshot$1) {
|
|
25356
|
-
return newQueryBoundFromDocument(query._query, query.firestore._databaseId, methodName, docOrFields[0]._document,
|
|
25550
|
+
return newQueryBoundFromDocument(query._query, query.firestore._databaseId, methodName, docOrFields[0]._document, inclusive);
|
|
25357
25551
|
}
|
|
25358
25552
|
else {
|
|
25359
25553
|
const reader = newUserDataReader(query.firestore);
|
|
25360
|
-
return newQueryBoundFromFields(query._query, query.firestore._databaseId, reader, methodName, docOrFields,
|
|
25554
|
+
return newQueryBoundFromFields(query._query, query.firestore._databaseId, reader, methodName, docOrFields, inclusive);
|
|
25361
25555
|
}
|
|
25362
25556
|
}
|
|
25363
25557
|
function newQueryFilter(query, methodName, dataReader, databaseId, fieldPath, op, value) {
|
|
@@ -25415,7 +25609,7 @@ function newQueryOrderBy(query, fieldPath, direction) {
|
|
|
25415
25609
|
* of the query or if any of the fields in the order by are an uncommitted
|
|
25416
25610
|
* server timestamp.
|
|
25417
25611
|
*/
|
|
25418
|
-
function newQueryBoundFromDocument(query, databaseId, methodName, doc,
|
|
25612
|
+
function newQueryBoundFromDocument(query, databaseId, methodName, doc, inclusive) {
|
|
25419
25613
|
if (!doc) {
|
|
25420
25614
|
throw new FirestoreError(Code.NOT_FOUND, `Can't use a DocumentSnapshot that doesn't exist for ` +
|
|
25421
25615
|
`${methodName}().`);
|
|
@@ -25452,12 +25646,12 @@ function newQueryBoundFromDocument(query, databaseId, methodName, doc, before) {
|
|
|
25452
25646
|
}
|
|
25453
25647
|
}
|
|
25454
25648
|
}
|
|
25455
|
-
return new Bound(components,
|
|
25649
|
+
return new Bound(components, inclusive);
|
|
25456
25650
|
}
|
|
25457
25651
|
/**
|
|
25458
25652
|
* Converts a list of field values to a `Bound` for the given query.
|
|
25459
25653
|
*/
|
|
25460
|
-
function newQueryBoundFromFields(query, databaseId, dataReader, methodName, values,
|
|
25654
|
+
function newQueryBoundFromFields(query, databaseId, dataReader, methodName, values, inclusive) {
|
|
25461
25655
|
// Use explicit order by's because it has to match the query the user made
|
|
25462
25656
|
const orderBy = query.explicitOrderBy;
|
|
25463
25657
|
if (values.length > orderBy.length) {
|
|
@@ -25494,7 +25688,7 @@ function newQueryBoundFromFields(query, databaseId, dataReader, methodName, valu
|
|
|
25494
25688
|
components.push(wrapped);
|
|
25495
25689
|
}
|
|
25496
25690
|
}
|
|
25497
|
-
return new Bound(components,
|
|
25691
|
+
return new Bound(components, inclusive);
|
|
25498
25692
|
}
|
|
25499
25693
|
/**
|
|
25500
25694
|
* Parses the given `documentIdValue` into a `ReferenceValue`, throwing
|