@firebase/firestore 3.4.6 → 3.4.7-2022222232915
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/CHANGELOG.md +11 -0
- package/dist/firestore/src/core/bundle.d.ts +2 -2
- package/dist/firestore/src/core/bundle_impl.d.ts +2 -0
- package/dist/firestore/src/core/query.d.ts +7 -0
- package/dist/firestore/src/core/snapshot_version.d.ts +1 -0
- package/dist/firestore/src/core/sync_engine_impl.d.ts +1 -1
- package/dist/firestore/src/local/indexeddb_mutation_batch_impl.d.ts +2 -1
- package/dist/firestore/src/local/indexeddb_remote_document_cache.d.ts +0 -17
- package/dist/firestore/src/local/indexeddb_schema.d.ts +16 -13
- package/dist/firestore/src/local/indexeddb_schema_converter.d.ts +1 -0
- package/dist/firestore/src/local/indexeddb_schema_legacy.d.ts +29 -0
- package/dist/firestore/src/local/indexeddb_sentinels.d.ts +22 -17
- package/dist/firestore/src/local/local_documents_view.d.ts +3 -4
- package/dist/firestore/src/local/local_serializer.d.ts +2 -1
- package/dist/firestore/src/local/local_store_impl.d.ts +1 -7
- package/dist/firestore/src/local/remote_document_cache.d.ts +13 -4
- package/dist/firestore/src/local/shared_client_state.d.ts +6 -3
- package/dist/firestore/src/local/shared_client_state_schema.d.ts +1 -1
- package/dist/firestore/src/local/shared_client_state_syncer.d.ts +1 -1
- package/dist/firestore/src/model/field_index.d.ts +8 -1
- package/dist/firestore/test/unit/local/test_remote_document_cache.d.ts +3 -1
- package/dist/index.esm2017.js +3206 -3134
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm5.js +3579 -3453
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +403 -244
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/index.node.mjs +403 -244
- package/dist/index.node.mjs.map +1 -1
- package/dist/index.rn.js +3160 -3088
- package/dist/index.rn.js.map +1 -1
- package/dist/internal.d.ts +19 -5
- package/dist/lite/firestore/src/core/bundle.d.ts +2 -2
- package/dist/lite/firestore/src/core/bundle_impl.d.ts +2 -0
- package/dist/lite/firestore/src/core/query.d.ts +7 -0
- package/dist/lite/firestore/src/core/snapshot_version.d.ts +1 -0
- package/dist/lite/firestore/src/core/sync_engine_impl.d.ts +1 -1
- package/dist/lite/firestore/src/local/indexeddb_mutation_batch_impl.d.ts +2 -1
- package/dist/lite/firestore/src/local/indexeddb_remote_document_cache.d.ts +0 -17
- package/dist/lite/firestore/src/local/indexeddb_schema.d.ts +16 -13
- package/dist/lite/firestore/src/local/indexeddb_schema_converter.d.ts +1 -0
- package/dist/lite/firestore/src/local/indexeddb_schema_legacy.d.ts +29 -0
- package/dist/lite/firestore/src/local/indexeddb_sentinels.d.ts +22 -17
- package/dist/lite/firestore/src/local/local_documents_view.d.ts +3 -4
- package/dist/lite/firestore/src/local/local_serializer.d.ts +2 -1
- package/dist/lite/firestore/src/local/local_store_impl.d.ts +1 -7
- package/dist/lite/firestore/src/local/remote_document_cache.d.ts +13 -4
- package/dist/lite/firestore/src/local/shared_client_state.d.ts +6 -3
- package/dist/lite/firestore/src/local/shared_client_state_schema.d.ts +1 -1
- package/dist/lite/firestore/src/local/shared_client_state_syncer.d.ts +1 -1
- package/dist/lite/firestore/src/model/field_index.d.ts +8 -1
- package/dist/lite/firestore/test/unit/local/test_remote_document_cache.d.ts +3 -1
- package/dist/lite/index.browser.esm2017.js +5 -2
- package/dist/lite/index.browser.esm2017.js.map +1 -1
- package/dist/lite/index.browser.esm5.js +94 -92
- package/dist/lite/index.browser.esm5.js.map +1 -1
- package/dist/lite/index.node.cjs.js +5 -2
- package/dist/lite/index.node.cjs.js.map +1 -1
- package/dist/lite/index.node.mjs +5 -2
- package/dist/lite/index.node.mjs.map +1 -1
- package/dist/lite/index.rn.esm2017.js +5 -2
- package/dist/lite/index.rn.esm2017.js.map +1 -1
- package/dist/lite/internal.d.ts +1 -0
- package/dist/lite/packages/firestore/src/core/bundle.d.ts +2 -2
- package/dist/lite/packages/firestore/src/core/bundle_impl.d.ts +2 -0
- package/dist/lite/packages/firestore/src/core/query.d.ts +7 -0
- package/dist/lite/packages/firestore/src/core/snapshot_version.d.ts +1 -0
- package/dist/lite/packages/firestore/src/core/sync_engine_impl.d.ts +1 -1
- package/dist/lite/packages/firestore/src/local/indexeddb_mutation_batch_impl.d.ts +2 -1
- package/dist/lite/packages/firestore/src/local/indexeddb_remote_document_cache.d.ts +0 -17
- package/dist/lite/packages/firestore/src/local/indexeddb_schema.d.ts +16 -13
- package/dist/lite/packages/firestore/src/local/indexeddb_schema_converter.d.ts +1 -0
- package/dist/lite/packages/firestore/src/local/indexeddb_schema_legacy.d.ts +29 -0
- package/dist/lite/packages/firestore/src/local/indexeddb_sentinels.d.ts +22 -17
- package/dist/lite/packages/firestore/src/local/local_documents_view.d.ts +3 -4
- package/dist/lite/packages/firestore/src/local/local_serializer.d.ts +2 -1
- package/dist/lite/packages/firestore/src/local/local_store_impl.d.ts +1 -7
- package/dist/lite/packages/firestore/src/local/remote_document_cache.d.ts +13 -4
- package/dist/lite/packages/firestore/src/local/shared_client_state.d.ts +6 -3
- package/dist/lite/packages/firestore/src/local/shared_client_state_schema.d.ts +1 -1
- package/dist/lite/packages/firestore/src/local/shared_client_state_syncer.d.ts +1 -1
- package/dist/lite/packages/firestore/src/model/field_index.d.ts +8 -1
- package/dist/lite/packages/firestore/test/unit/local/test_remote_document_cache.d.ts +3 -1
- package/dist/lite/private.d.ts +1 -0
- package/dist/packages/firestore/dist/index.esm2017.d.ts +178 -178
- package/dist/packages/firestore/src/core/bundle.d.ts +2 -2
- package/dist/packages/firestore/src/core/bundle_impl.d.ts +2 -0
- package/dist/packages/firestore/src/core/query.d.ts +7 -0
- package/dist/packages/firestore/src/core/snapshot_version.d.ts +1 -0
- package/dist/packages/firestore/src/core/sync_engine_impl.d.ts +1 -1
- package/dist/packages/firestore/src/local/indexeddb_mutation_batch_impl.d.ts +2 -1
- package/dist/packages/firestore/src/local/indexeddb_remote_document_cache.d.ts +0 -17
- package/dist/packages/firestore/src/local/indexeddb_schema.d.ts +16 -13
- package/dist/packages/firestore/src/local/indexeddb_schema_converter.d.ts +1 -0
- package/dist/packages/firestore/src/local/indexeddb_schema_legacy.d.ts +29 -0
- package/dist/packages/firestore/src/local/indexeddb_sentinels.d.ts +22 -17
- package/dist/packages/firestore/src/local/local_documents_view.d.ts +3 -4
- package/dist/packages/firestore/src/local/local_serializer.d.ts +2 -1
- package/dist/packages/firestore/src/local/local_store_impl.d.ts +1 -7
- package/dist/packages/firestore/src/local/remote_document_cache.d.ts +13 -4
- package/dist/packages/firestore/src/local/shared_client_state.d.ts +6 -3
- package/dist/packages/firestore/src/local/shared_client_state_schema.d.ts +1 -1
- package/dist/packages/firestore/src/local/shared_client_state_syncer.d.ts +1 -1
- package/dist/packages/firestore/src/model/field_index.d.ts +8 -1
- package/dist/packages/firestore/test/unit/local/test_remote_document_cache.d.ts +3 -1
- package/dist/private.d.ts +19 -5
- package/package.json +7 -7
package/dist/index.node.cjs.js
CHANGED
|
@@ -33,7 +33,7 @@ var grpc__namespace = /*#__PURE__*/_interopNamespace(grpc);
|
|
|
33
33
|
var protoLoader__namespace = /*#__PURE__*/_interopNamespace(protoLoader);
|
|
34
34
|
|
|
35
35
|
const name = "@firebase/firestore";
|
|
36
|
-
const version$1 = "3.4.
|
|
36
|
+
const version$1 = "3.4.7-2022222232915";
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
39
|
* @license
|
|
@@ -86,7 +86,7 @@ User.GOOGLE_CREDENTIALS = new User('google-credentials-uid');
|
|
|
86
86
|
User.FIRST_PARTY = new User('first-party-uid');
|
|
87
87
|
User.MOCK_USER = new User('mock-user');
|
|
88
88
|
|
|
89
|
-
const version = "9.6.
|
|
89
|
+
const version = "9.6.10-2022222232915";
|
|
90
90
|
|
|
91
91
|
/**
|
|
92
92
|
* @license
|
|
@@ -1225,6 +1225,24 @@ function decodeResourcePath(path) {
|
|
|
1225
1225
|
return new ResourcePath(segments);
|
|
1226
1226
|
}
|
|
1227
1227
|
|
|
1228
|
+
/**
|
|
1229
|
+
* @license
|
|
1230
|
+
* Copyright 2022 Google LLC
|
|
1231
|
+
*
|
|
1232
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1233
|
+
* you may not use this file except in compliance with the License.
|
|
1234
|
+
* You may obtain a copy of the License at
|
|
1235
|
+
*
|
|
1236
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1237
|
+
*
|
|
1238
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
1239
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1240
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1241
|
+
* See the License for the specific language governing permissions and
|
|
1242
|
+
* limitations under the License.
|
|
1243
|
+
*/
|
|
1244
|
+
const DbRemoteDocumentStore$1 = 'remoteDocuments';
|
|
1245
|
+
|
|
1228
1246
|
/**
|
|
1229
1247
|
* @license
|
|
1230
1248
|
* Copyright 2022 Google LLC
|
|
@@ -1295,26 +1313,36 @@ function newDbDocumentMutationKey(userId, path, batchId) {
|
|
|
1295
1313
|
*/
|
|
1296
1314
|
const DbDocumentMutationPlaceholder = {};
|
|
1297
1315
|
const DbDocumentMutationStore = 'documentMutations';
|
|
1298
|
-
const DbRemoteDocumentStore = '
|
|
1316
|
+
const DbRemoteDocumentStore = 'remoteDocumentsV14';
|
|
1299
1317
|
/**
|
|
1300
|
-
*
|
|
1301
|
-
*
|
|
1302
|
-
*
|
|
1303
|
-
* This index is used to provide a changelog for Multi-Tab.
|
|
1318
|
+
* The primary key of the remote documents store, which allows for efficient
|
|
1319
|
+
* access by collection path and read time.
|
|
1304
1320
|
*/
|
|
1305
|
-
const
|
|
1306
|
-
|
|
1321
|
+
const DbRemoteDocumentKeyPath = [
|
|
1322
|
+
'prefixPath',
|
|
1323
|
+
'collectionGroup',
|
|
1324
|
+
'readTime',
|
|
1325
|
+
'documentId'
|
|
1326
|
+
];
|
|
1327
|
+
/** An index that provides access to documents by key. */
|
|
1328
|
+
const DbRemoteDocumentDocumentKeyIndex = 'documentKeyIndex';
|
|
1329
|
+
const DbRemoteDocumentDocumentKeyIndexPath = [
|
|
1330
|
+
'prefixPath',
|
|
1331
|
+
'collectionGroup',
|
|
1332
|
+
'documentId'
|
|
1333
|
+
];
|
|
1307
1334
|
/**
|
|
1308
|
-
* An index that provides access to documents
|
|
1335
|
+
* An index that provides access to documents by collection group and read
|
|
1309
1336
|
* time.
|
|
1310
1337
|
*
|
|
1311
|
-
* This index is used
|
|
1312
|
-
* documents in a collection.
|
|
1338
|
+
* This index is used by the index backfiller.
|
|
1313
1339
|
*/
|
|
1314
|
-
const
|
|
1315
|
-
const
|
|
1316
|
-
'
|
|
1317
|
-
'readTime'
|
|
1340
|
+
const DbRemoteDocumentCollectionGroupIndex = 'collectionGroupIndex';
|
|
1341
|
+
const DbRemoteDocumentCollectionGroupIndexPath = [
|
|
1342
|
+
'collectionGroup',
|
|
1343
|
+
'readTime',
|
|
1344
|
+
'prefixPath',
|
|
1345
|
+
'documentId'
|
|
1318
1346
|
];
|
|
1319
1347
|
const DbRemoteDocumentGlobalStore = 'remoteDocumentGlobal';
|
|
1320
1348
|
const DbRemoteDocumentGlobalKey = 'remoteDocumentGlobalKey';
|
|
@@ -1422,7 +1450,7 @@ const V1_STORES = [
|
|
|
1422
1450
|
DbMutationQueueStore,
|
|
1423
1451
|
DbMutationBatchStore,
|
|
1424
1452
|
DbDocumentMutationStore,
|
|
1425
|
-
DbRemoteDocumentStore,
|
|
1453
|
+
DbRemoteDocumentStore$1,
|
|
1426
1454
|
DbTargetStore,
|
|
1427
1455
|
DbPrimaryClientStore,
|
|
1428
1456
|
DbTargetGlobalStore,
|
|
@@ -1437,14 +1465,33 @@ const V8_STORES = [...V6_STORES, DbCollectionParentStore];
|
|
|
1437
1465
|
const V11_STORES = [...V8_STORES, DbBundleStore, DbNamedQueryStore];
|
|
1438
1466
|
const V12_STORES = [...V11_STORES, DbDocumentOverlayStore];
|
|
1439
1467
|
const V13_STORES = [
|
|
1440
|
-
|
|
1468
|
+
DbMutationQueueStore,
|
|
1469
|
+
DbMutationBatchStore,
|
|
1470
|
+
DbDocumentMutationStore,
|
|
1471
|
+
DbRemoteDocumentStore,
|
|
1472
|
+
DbTargetStore,
|
|
1473
|
+
DbPrimaryClientStore,
|
|
1474
|
+
DbTargetGlobalStore,
|
|
1475
|
+
DbTargetDocumentStore,
|
|
1476
|
+
DbClientMetadataStore,
|
|
1477
|
+
DbRemoteDocumentGlobalStore,
|
|
1478
|
+
DbCollectionParentStore,
|
|
1479
|
+
DbBundleStore,
|
|
1480
|
+
DbNamedQueryStore,
|
|
1481
|
+
DbDocumentOverlayStore
|
|
1482
|
+
];
|
|
1483
|
+
const V14_STORES = [
|
|
1484
|
+
...V13_STORES,
|
|
1441
1485
|
DbIndexConfigurationStore,
|
|
1442
1486
|
DbIndexStateStore,
|
|
1443
1487
|
DbIndexEntryStore
|
|
1444
1488
|
];
|
|
1445
1489
|
/** Returns the object stores for the provided schema. */
|
|
1446
1490
|
function getObjectStores(schemaVersion) {
|
|
1447
|
-
if (schemaVersion ===
|
|
1491
|
+
if (schemaVersion === 14) {
|
|
1492
|
+
return V14_STORES;
|
|
1493
|
+
}
|
|
1494
|
+
else if (schemaVersion === 13) {
|
|
1448
1495
|
return V13_STORES;
|
|
1449
1496
|
}
|
|
1450
1497
|
else if (schemaVersion === 12) {
|
|
@@ -2655,6 +2702,9 @@ class SnapshotVersion {
|
|
|
2655
2702
|
static min() {
|
|
2656
2703
|
return new SnapshotVersion(new Timestamp(0, 0));
|
|
2657
2704
|
}
|
|
2705
|
+
static max() {
|
|
2706
|
+
return new SnapshotVersion(new Timestamp(253402300799, 1e9 - 1));
|
|
2707
|
+
}
|
|
2658
2708
|
compareTo(other) {
|
|
2659
2709
|
return this.timestamp._compareTo(other.timestamp);
|
|
2660
2710
|
}
|
|
@@ -4206,6 +4256,28 @@ class IndexState {
|
|
|
4206
4256
|
return new IndexState(INITIAL_SEQUENCE_NUMBER, IndexOffset.min());
|
|
4207
4257
|
}
|
|
4208
4258
|
}
|
|
4259
|
+
/**
|
|
4260
|
+
* Creates an offset that matches all documents with a read time higher than
|
|
4261
|
+
* `readTime`.
|
|
4262
|
+
*/
|
|
4263
|
+
function newIndexOffsetSuccessorFromReadTime(readTime, largestBatchId) {
|
|
4264
|
+
// We want to create an offset that matches all documents with a read time
|
|
4265
|
+
// greater than the provided read time. To do so, we technically need to
|
|
4266
|
+
// create an offset for `(readTime, MAX_DOCUMENT_KEY)`. While we could use
|
|
4267
|
+
// Unicode codepoints to generate MAX_DOCUMENT_KEY, it is much easier to use
|
|
4268
|
+
// `(readTime + 1, DocumentKey.empty())` since `> DocumentKey.empty()` matches
|
|
4269
|
+
// all valid document IDs.
|
|
4270
|
+
const successorSeconds = readTime.toTimestamp().seconds;
|
|
4271
|
+
const successorNanos = readTime.toTimestamp().nanoseconds + 1;
|
|
4272
|
+
const successor = SnapshotVersion.fromTimestamp(successorNanos === 1e9
|
|
4273
|
+
? new Timestamp(successorSeconds + 1, 0)
|
|
4274
|
+
: new Timestamp(successorSeconds, successorNanos));
|
|
4275
|
+
return new IndexOffset(successor, DocumentKey.empty(), largestBatchId);
|
|
4276
|
+
}
|
|
4277
|
+
/** Creates a new offset based on the provided document. */
|
|
4278
|
+
function newIndexOffsetFromDocument(document) {
|
|
4279
|
+
return new IndexOffset(document.readTime, document.key, INITIAL_LARGEST_BATCH_ID);
|
|
4280
|
+
}
|
|
4209
4281
|
/**
|
|
4210
4282
|
* Stores the latest read time, document and batch ID that were processed for an
|
|
4211
4283
|
* index.
|
|
@@ -4230,10 +4302,25 @@ class IndexOffset {
|
|
|
4230
4302
|
this.documentKey = documentKey;
|
|
4231
4303
|
this.largestBatchId = largestBatchId;
|
|
4232
4304
|
}
|
|
4233
|
-
/**
|
|
4305
|
+
/** Returns an offset that sorts before all regular offsets. */
|
|
4234
4306
|
static min() {
|
|
4235
4307
|
return new IndexOffset(SnapshotVersion.min(), DocumentKey.empty(), INITIAL_LARGEST_BATCH_ID);
|
|
4236
4308
|
}
|
|
4309
|
+
/** Returns an offset that sorts after all regular offsets. */
|
|
4310
|
+
static max() {
|
|
4311
|
+
return new IndexOffset(SnapshotVersion.max(), DocumentKey.empty(), INITIAL_LARGEST_BATCH_ID);
|
|
4312
|
+
}
|
|
4313
|
+
}
|
|
4314
|
+
function indexOffsetComparator(left, right) {
|
|
4315
|
+
let cmp = left.readTime.compareTo(right.readTime);
|
|
4316
|
+
if (cmp !== 0) {
|
|
4317
|
+
return cmp;
|
|
4318
|
+
}
|
|
4319
|
+
cmp = DocumentKey.comparator(left.documentKey, right.documentKey);
|
|
4320
|
+
if (cmp !== 0) {
|
|
4321
|
+
return cmp;
|
|
4322
|
+
}
|
|
4323
|
+
return primitiveComparator(left.largestBatchId, right.largestBatchId);
|
|
4237
4324
|
}
|
|
4238
4325
|
|
|
4239
4326
|
/**
|
|
@@ -5126,6 +5213,18 @@ function queryMatchesBounds(query, doc) {
|
|
|
5126
5213
|
}
|
|
5127
5214
|
return true;
|
|
5128
5215
|
}
|
|
5216
|
+
/**
|
|
5217
|
+
* Returns the collection group that this query targets.
|
|
5218
|
+
*
|
|
5219
|
+
* PORTING NOTE: This is only used in the Web SDK to facilitate multi-tab
|
|
5220
|
+
* synchronization for query results.
|
|
5221
|
+
*/
|
|
5222
|
+
function queryCollectionGroup(query) {
|
|
5223
|
+
return (query.collectionGroup ||
|
|
5224
|
+
(query.path.length % 2 === 1
|
|
5225
|
+
? query.path.lastSegment()
|
|
5226
|
+
: query.path.get(query.path.length - 2)));
|
|
5227
|
+
}
|
|
5129
5228
|
/**
|
|
5130
5229
|
* Returns a new comparator function that can be used to compare two documents
|
|
5131
5230
|
* based on the Query's ordering constraint.
|
|
@@ -8659,40 +8758,33 @@ function fromDbRemoteDocument(localSerializer, remoteDoc) {
|
|
|
8659
8758
|
}
|
|
8660
8759
|
/** Encodes a document for storage locally. */
|
|
8661
8760
|
function toDbRemoteDocument(localSerializer, document) {
|
|
8662
|
-
const
|
|
8663
|
-
const
|
|
8761
|
+
const key = document.key;
|
|
8762
|
+
const remoteDoc = {
|
|
8763
|
+
prefixPath: key.getCollectionPath().popLast().toArray(),
|
|
8764
|
+
collectionGroup: key.collectionGroup,
|
|
8765
|
+
documentId: key.path.lastSegment(),
|
|
8766
|
+
readTime: toDbTimestampKey(document.readTime),
|
|
8767
|
+
hasCommittedMutations: document.hasCommittedMutations
|
|
8768
|
+
};
|
|
8664
8769
|
if (document.isFoundDocument()) {
|
|
8665
|
-
|
|
8666
|
-
const hasCommittedMutations = document.hasCommittedMutations;
|
|
8667
|
-
return {
|
|
8668
|
-
document: doc,
|
|
8669
|
-
hasCommittedMutations,
|
|
8670
|
-
readTime,
|
|
8671
|
-
parentPath
|
|
8672
|
-
};
|
|
8770
|
+
remoteDoc.document = toDocument(localSerializer.remoteSerializer, document);
|
|
8673
8771
|
}
|
|
8674
8772
|
else if (document.isNoDocument()) {
|
|
8675
|
-
|
|
8676
|
-
|
|
8677
|
-
|
|
8678
|
-
noDocument: { path, readTime: toDbTimestamp(document.version) },
|
|
8679
|
-
hasCommittedMutations,
|
|
8680
|
-
readTime,
|
|
8681
|
-
parentPath
|
|
8773
|
+
remoteDoc.noDocument = {
|
|
8774
|
+
path: key.path.toArray(),
|
|
8775
|
+
readTime: toDbTimestamp(document.version)
|
|
8682
8776
|
};
|
|
8683
8777
|
}
|
|
8684
8778
|
else if (document.isUnknownDocument()) {
|
|
8685
|
-
|
|
8686
|
-
|
|
8687
|
-
|
|
8688
|
-
hasCommittedMutations: true,
|
|
8689
|
-
readTime,
|
|
8690
|
-
parentPath
|
|
8779
|
+
remoteDoc.unknownDocument = {
|
|
8780
|
+
path: key.path.toArray(),
|
|
8781
|
+
version: toDbTimestamp(document.version)
|
|
8691
8782
|
};
|
|
8692
8783
|
}
|
|
8693
8784
|
else {
|
|
8694
8785
|
return fail();
|
|
8695
8786
|
}
|
|
8787
|
+
return remoteDoc;
|
|
8696
8788
|
}
|
|
8697
8789
|
function toDbTimestampKey(snapshotVersion) {
|
|
8698
8790
|
const timestamp = snapshotVersion.toTimestamp();
|
|
@@ -11844,7 +11936,7 @@ class IndexedDbRemoteDocumentCacheImpl {
|
|
|
11844
11936
|
*/
|
|
11845
11937
|
addEntry(transaction, key, doc) {
|
|
11846
11938
|
const documentStore = remoteDocumentsStore(transaction);
|
|
11847
|
-
return documentStore.put(
|
|
11939
|
+
return documentStore.put(doc);
|
|
11848
11940
|
}
|
|
11849
11941
|
/**
|
|
11850
11942
|
* Removes a document from the cache.
|
|
@@ -11852,10 +11944,9 @@ class IndexedDbRemoteDocumentCacheImpl {
|
|
|
11852
11944
|
* All calls of `removeEntry` are required to go through the RemoteDocumentChangeBuffer
|
|
11853
11945
|
* returned by `newChangeBuffer()` to ensure proper accounting of metadata.
|
|
11854
11946
|
*/
|
|
11855
|
-
removeEntry(transaction, documentKey) {
|
|
11947
|
+
removeEntry(transaction, documentKey, readTime) {
|
|
11856
11948
|
const store = remoteDocumentsStore(transaction);
|
|
11857
|
-
|
|
11858
|
-
return store.delete(key);
|
|
11949
|
+
return store.delete(dbReadTimeKey(documentKey, readTime));
|
|
11859
11950
|
}
|
|
11860
11951
|
/**
|
|
11861
11952
|
* Updates the current cache size.
|
|
@@ -11870,11 +11961,15 @@ class IndexedDbRemoteDocumentCacheImpl {
|
|
|
11870
11961
|
});
|
|
11871
11962
|
}
|
|
11872
11963
|
getEntry(transaction, documentKey) {
|
|
11964
|
+
let doc = MutableDocument.newInvalidDocument(documentKey);
|
|
11873
11965
|
return remoteDocumentsStore(transaction)
|
|
11874
|
-
.
|
|
11875
|
-
|
|
11876
|
-
|
|
11877
|
-
})
|
|
11966
|
+
.iterate({
|
|
11967
|
+
index: DbRemoteDocumentDocumentKeyIndex,
|
|
11968
|
+
range: IDBKeyRange.only(dbKey(documentKey))
|
|
11969
|
+
}, (_, dbRemoteDoc) => {
|
|
11970
|
+
doc = this.maybeDecodeDocument(documentKey, dbRemoteDoc);
|
|
11971
|
+
})
|
|
11972
|
+
.next(() => doc);
|
|
11878
11973
|
}
|
|
11879
11974
|
/**
|
|
11880
11975
|
* Looks up an entry in the cache.
|
|
@@ -11883,15 +11978,21 @@ class IndexedDbRemoteDocumentCacheImpl {
|
|
|
11883
11978
|
* @returns The cached document entry and its size.
|
|
11884
11979
|
*/
|
|
11885
11980
|
getSizedEntry(transaction, documentKey) {
|
|
11981
|
+
let result = {
|
|
11982
|
+
size: 0,
|
|
11983
|
+
document: MutableDocument.newInvalidDocument(documentKey)
|
|
11984
|
+
};
|
|
11886
11985
|
return remoteDocumentsStore(transaction)
|
|
11887
|
-
.
|
|
11888
|
-
|
|
11889
|
-
|
|
11890
|
-
|
|
11891
|
-
|
|
11986
|
+
.iterate({
|
|
11987
|
+
index: DbRemoteDocumentDocumentKeyIndex,
|
|
11988
|
+
range: IDBKeyRange.only(dbKey(documentKey))
|
|
11989
|
+
}, (_, dbRemoteDoc) => {
|
|
11990
|
+
result = {
|
|
11991
|
+
document: this.maybeDecodeDocument(documentKey, dbRemoteDoc),
|
|
11892
11992
|
size: dbDocumentSize(dbRemoteDoc)
|
|
11893
11993
|
};
|
|
11894
|
-
})
|
|
11994
|
+
})
|
|
11995
|
+
.next(() => result);
|
|
11895
11996
|
}
|
|
11896
11997
|
getEntries(transaction, documentKeys) {
|
|
11897
11998
|
let results = mutableDocumentMap();
|
|
@@ -11922,14 +12023,20 @@ class IndexedDbRemoteDocumentCacheImpl {
|
|
|
11922
12023
|
if (documentKeys.isEmpty()) {
|
|
11923
12024
|
return PersistencePromise.resolve();
|
|
11924
12025
|
}
|
|
11925
|
-
|
|
11926
|
-
|
|
12026
|
+
let sortedKeys = new SortedSet(dbKeyComparator);
|
|
12027
|
+
documentKeys.forEach(e => (sortedKeys = sortedKeys.add(e)));
|
|
12028
|
+
const range = IDBKeyRange.bound(dbKey(sortedKeys.first()), dbKey(sortedKeys.last()));
|
|
12029
|
+
const keyIter = sortedKeys.getIterator();
|
|
11927
12030
|
let nextKey = keyIter.getNext();
|
|
11928
12031
|
return remoteDocumentsStore(transaction)
|
|
11929
|
-
.iterate({ range }, (
|
|
11930
|
-
const potentialKey = DocumentKey.fromSegments(
|
|
12032
|
+
.iterate({ index: DbRemoteDocumentDocumentKeyIndex, range }, (_, dbRemoteDoc, control) => {
|
|
12033
|
+
const potentialKey = DocumentKey.fromSegments([
|
|
12034
|
+
...dbRemoteDoc.prefixPath,
|
|
12035
|
+
dbRemoteDoc.collectionGroup,
|
|
12036
|
+
dbRemoteDoc.documentId
|
|
12037
|
+
]);
|
|
11931
12038
|
// Go through keys not found in cache.
|
|
11932
|
-
while (nextKey &&
|
|
12039
|
+
while (nextKey && dbKeyComparator(nextKey, potentialKey) < 0) {
|
|
11933
12040
|
callback(nextKey, null);
|
|
11934
12041
|
nextKey = keyIter.getNext();
|
|
11935
12042
|
}
|
|
@@ -11940,7 +12047,7 @@ class IndexedDbRemoteDocumentCacheImpl {
|
|
|
11940
12047
|
}
|
|
11941
12048
|
// Skip to the next key (if there is one).
|
|
11942
12049
|
if (nextKey) {
|
|
11943
|
-
control.skip(nextKey
|
|
12050
|
+
control.skip(dbKey(nextKey));
|
|
11944
12051
|
}
|
|
11945
12052
|
else {
|
|
11946
12053
|
control.done();
|
|
@@ -11955,41 +12062,44 @@ class IndexedDbRemoteDocumentCacheImpl {
|
|
|
11955
12062
|
}
|
|
11956
12063
|
});
|
|
11957
12064
|
}
|
|
11958
|
-
|
|
11959
|
-
|
|
11960
|
-
|
|
11961
|
-
|
|
11962
|
-
|
|
11963
|
-
|
|
11964
|
-
|
|
11965
|
-
|
|
11966
|
-
|
|
11967
|
-
|
|
11968
|
-
|
|
11969
|
-
|
|
11970
|
-
|
|
11971
|
-
|
|
11972
|
-
|
|
11973
|
-
const readTimeKey = toDbTimestampKey(sinceReadTime);
|
|
11974
|
-
iterationOptions.range = IDBKeyRange.lowerBound([collectionKey, readTimeKey],
|
|
11975
|
-
/* open= */ true);
|
|
11976
|
-
iterationOptions.index = DbRemoteDocumentCollectionReadTimeIndex;
|
|
11977
|
-
}
|
|
12065
|
+
getAllFromCollection(transaction, collection, offset) {
|
|
12066
|
+
const startKey = [
|
|
12067
|
+
collection.popLast().toArray(),
|
|
12068
|
+
collection.lastSegment(),
|
|
12069
|
+
toDbTimestampKey(offset.readTime),
|
|
12070
|
+
offset.documentKey.path.isEmpty()
|
|
12071
|
+
? ''
|
|
12072
|
+
: offset.documentKey.path.lastSegment()
|
|
12073
|
+
];
|
|
12074
|
+
const endKey = [
|
|
12075
|
+
collection.popLast().toArray(),
|
|
12076
|
+
collection.lastSegment(),
|
|
12077
|
+
[Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER],
|
|
12078
|
+
''
|
|
12079
|
+
];
|
|
11978
12080
|
return remoteDocumentsStore(transaction)
|
|
11979
|
-
.
|
|
11980
|
-
|
|
11981
|
-
|
|
11982
|
-
|
|
11983
|
-
|
|
11984
|
-
// more than one segment longer than the query path.
|
|
11985
|
-
if (key.length !== immediateChildrenPathLength) {
|
|
11986
|
-
return;
|
|
11987
|
-
}
|
|
11988
|
-
const document = this.maybeDecodeDocument(DocumentKey.fromSegments(key), dbRemoteDoc);
|
|
11989
|
-
if (collection.isPrefixOf(document.key.path)) {
|
|
12081
|
+
.loadAll(IDBKeyRange.bound(startKey, endKey, true))
|
|
12082
|
+
.next(dbRemoteDocs => {
|
|
12083
|
+
let results = mutableDocumentMap();
|
|
12084
|
+
for (const dbRemoteDoc of dbRemoteDocs) {
|
|
12085
|
+
const document = this.maybeDecodeDocument(DocumentKey.fromSegments(dbRemoteDoc.prefixPath.concat(dbRemoteDoc.collectionGroup, dbRemoteDoc.documentId)), dbRemoteDoc);
|
|
11990
12086
|
results = results.insert(document.key, document);
|
|
11991
12087
|
}
|
|
11992
|
-
|
|
12088
|
+
return results;
|
|
12089
|
+
});
|
|
12090
|
+
}
|
|
12091
|
+
getAllFromCollectionGroup(transaction, collectionGroup, offset, limit) {
|
|
12092
|
+
let results = mutableDocumentMap();
|
|
12093
|
+
const startKey = dbCollectionGroupKey(collectionGroup, offset);
|
|
12094
|
+
const endKey = dbCollectionGroupKey(collectionGroup, IndexOffset.max());
|
|
12095
|
+
return remoteDocumentsStore(transaction)
|
|
12096
|
+
.iterate({
|
|
12097
|
+
index: DbRemoteDocumentCollectionGroupIndex,
|
|
12098
|
+
range: IDBKeyRange.bound(startKey, endKey, true)
|
|
12099
|
+
}, (_, dbRemoteDoc, control) => {
|
|
12100
|
+
const document = this.maybeDecodeDocument(DocumentKey.fromSegments(dbRemoteDoc.prefixPath.concat(dbRemoteDoc.collectionGroup, dbRemoteDoc.documentId)), dbRemoteDoc);
|
|
12101
|
+
results = results.insert(document.key, document);
|
|
12102
|
+
if (results.size === limit) {
|
|
11993
12103
|
control.done();
|
|
11994
12104
|
}
|
|
11995
12105
|
})
|
|
@@ -12033,50 +12143,6 @@ class IndexedDbRemoteDocumentCacheImpl {
|
|
|
12033
12143
|
function newIndexedDbRemoteDocumentCache(serializer) {
|
|
12034
12144
|
return new IndexedDbRemoteDocumentCacheImpl(serializer);
|
|
12035
12145
|
}
|
|
12036
|
-
/**
|
|
12037
|
-
* Returns the set of documents that have changed since the specified read
|
|
12038
|
-
* time.
|
|
12039
|
-
*/
|
|
12040
|
-
// PORTING NOTE: This is only used for multi-tab synchronization.
|
|
12041
|
-
function remoteDocumentCacheGetNewDocumentChanges(remoteDocumentCache, transaction, sinceReadTime) {
|
|
12042
|
-
const remoteDocumentCacheImpl = debugCast(remoteDocumentCache);
|
|
12043
|
-
let changedDocs = mutableDocumentMap();
|
|
12044
|
-
let lastReadTime = toDbTimestampKey(sinceReadTime);
|
|
12045
|
-
const documentsStore = remoteDocumentsStore(transaction);
|
|
12046
|
-
const range = IDBKeyRange.lowerBound(lastReadTime, true);
|
|
12047
|
-
return documentsStore
|
|
12048
|
-
.iterate({ index: DbRemoteDocumentReadTimeIndex, range }, (_, dbRemoteDoc) => {
|
|
12049
|
-
// Unlike `getEntry()` and others, `getNewDocumentChanges()` parses
|
|
12050
|
-
// the documents directly since we want to keep sentinel deletes.
|
|
12051
|
-
const doc = fromDbRemoteDocument(remoteDocumentCacheImpl.serializer, dbRemoteDoc);
|
|
12052
|
-
changedDocs = changedDocs.insert(doc.key, doc);
|
|
12053
|
-
lastReadTime = dbRemoteDoc.readTime;
|
|
12054
|
-
})
|
|
12055
|
-
.next(() => {
|
|
12056
|
-
return {
|
|
12057
|
-
changedDocs,
|
|
12058
|
-
readTime: fromDbTimestampKey(lastReadTime)
|
|
12059
|
-
};
|
|
12060
|
-
});
|
|
12061
|
-
}
|
|
12062
|
-
/**
|
|
12063
|
-
* Returns the read time of the most recently read document in the cache, or
|
|
12064
|
-
* SnapshotVersion.min() if not available.
|
|
12065
|
-
*/
|
|
12066
|
-
// PORTING NOTE: This is only used for multi-tab synchronization.
|
|
12067
|
-
function remoteDocumentCacheGetLastReadTime(transaction) {
|
|
12068
|
-
const documentsStore = remoteDocumentsStore(transaction);
|
|
12069
|
-
// If there are no existing entries, we return SnapshotVersion.min().
|
|
12070
|
-
let readTime = SnapshotVersion.min();
|
|
12071
|
-
return documentsStore
|
|
12072
|
-
.iterate({ index: DbRemoteDocumentReadTimeIndex, reverse: true }, (key, dbRemoteDoc, control) => {
|
|
12073
|
-
if (dbRemoteDoc.readTime) {
|
|
12074
|
-
readTime = fromDbTimestampKey(dbRemoteDoc.readTime);
|
|
12075
|
-
}
|
|
12076
|
-
control.done();
|
|
12077
|
-
})
|
|
12078
|
-
.next(() => readTime);
|
|
12079
|
-
}
|
|
12080
12146
|
/**
|
|
12081
12147
|
* Handles the details of adding and updating documents in the IndexedDbRemoteDocumentCache.
|
|
12082
12148
|
*
|
|
@@ -12094,24 +12160,26 @@ class IndexedDbRemoteDocumentChangeBuffer extends RemoteDocumentChangeBuffer {
|
|
|
12094
12160
|
super();
|
|
12095
12161
|
this.documentCache = documentCache;
|
|
12096
12162
|
this.trackRemovals = trackRemovals;
|
|
12097
|
-
// A map of document sizes prior to applying the changes in
|
|
12098
|
-
this
|
|
12163
|
+
// A map of document sizes and read times prior to applying the changes in
|
|
12164
|
+
// this buffer.
|
|
12165
|
+
this.documentStates = new ObjectMap(key => key.toString(), (l, r) => l.isEqual(r));
|
|
12099
12166
|
}
|
|
12100
12167
|
applyChanges(transaction) {
|
|
12101
12168
|
const promises = [];
|
|
12102
12169
|
let sizeDelta = 0;
|
|
12103
12170
|
let collectionParents = new SortedSet((l, r) => primitiveComparator(l.canonicalString(), r.canonicalString()));
|
|
12104
12171
|
this.changes.forEach((key, documentChange) => {
|
|
12105
|
-
const
|
|
12172
|
+
const previousDoc = this.documentStates.get(key);
|
|
12173
|
+
promises.push(this.documentCache.removeEntry(transaction, key, previousDoc.readTime));
|
|
12106
12174
|
if (documentChange.isValidDocument()) {
|
|
12107
12175
|
const doc = toDbRemoteDocument(this.documentCache.serializer, documentChange);
|
|
12108
12176
|
collectionParents = collectionParents.add(key.path.popLast());
|
|
12109
12177
|
const size = dbDocumentSize(doc);
|
|
12110
|
-
sizeDelta += size -
|
|
12178
|
+
sizeDelta += size - previousDoc.size;
|
|
12111
12179
|
promises.push(this.documentCache.addEntry(transaction, key, doc));
|
|
12112
12180
|
}
|
|
12113
12181
|
else {
|
|
12114
|
-
sizeDelta -=
|
|
12182
|
+
sizeDelta -= previousDoc.size;
|
|
12115
12183
|
if (this.trackRemovals) {
|
|
12116
12184
|
// In order to track removals, we store a "sentinel delete" in the
|
|
12117
12185
|
// RemoteDocumentCache. This entry is represented by a NoDocument
|
|
@@ -12120,9 +12188,6 @@ class IndexedDbRemoteDocumentChangeBuffer extends RemoteDocumentChangeBuffer {
|
|
|
12120
12188
|
const deletedDoc = toDbRemoteDocument(this.documentCache.serializer, documentChange.convertToNoDocument(SnapshotVersion.min()));
|
|
12121
12189
|
promises.push(this.documentCache.addEntry(transaction, key, deletedDoc));
|
|
12122
12190
|
}
|
|
12123
|
-
else {
|
|
12124
|
-
promises.push(this.documentCache.removeEntry(transaction, key));
|
|
12125
|
-
}
|
|
12126
12191
|
}
|
|
12127
12192
|
});
|
|
12128
12193
|
collectionParents.forEach(parent => {
|
|
@@ -12136,7 +12201,10 @@ class IndexedDbRemoteDocumentChangeBuffer extends RemoteDocumentChangeBuffer {
|
|
|
12136
12201
|
return this.documentCache
|
|
12137
12202
|
.getSizedEntry(transaction, documentKey)
|
|
12138
12203
|
.next(getResult => {
|
|
12139
|
-
this.
|
|
12204
|
+
this.documentStates.set(documentKey, {
|
|
12205
|
+
size: getResult.size,
|
|
12206
|
+
readTime: getResult.document.readTime
|
|
12207
|
+
});
|
|
12140
12208
|
return getResult.document;
|
|
12141
12209
|
});
|
|
12142
12210
|
}
|
|
@@ -12150,7 +12218,10 @@ class IndexedDbRemoteDocumentChangeBuffer extends RemoteDocumentChangeBuffer {
|
|
|
12150
12218
|
// keys to `DocumentSizeEntry`s. This is to allow returning the
|
|
12151
12219
|
// `MutableDocumentMap` directly, without a conversion.
|
|
12152
12220
|
sizeMap.forEach((documentKey, size) => {
|
|
12153
|
-
this.
|
|
12221
|
+
this.documentStates.set(documentKey, {
|
|
12222
|
+
size,
|
|
12223
|
+
readTime: documents.get(documentKey).readTime
|
|
12224
|
+
});
|
|
12154
12225
|
});
|
|
12155
12226
|
return documents;
|
|
12156
12227
|
});
|
|
@@ -12165,8 +12236,52 @@ function documentGlobalStore(txn) {
|
|
|
12165
12236
|
function remoteDocumentsStore(txn) {
|
|
12166
12237
|
return getStore(txn, DbRemoteDocumentStore);
|
|
12167
12238
|
}
|
|
12168
|
-
|
|
12169
|
-
|
|
12239
|
+
/**
|
|
12240
|
+
* Returns a key that can be used for document lookups on the
|
|
12241
|
+
* `DbRemoteDocumentDocumentKeyIndex` index.
|
|
12242
|
+
*/
|
|
12243
|
+
function dbKey(documentKey) {
|
|
12244
|
+
const path = documentKey.path.toArray();
|
|
12245
|
+
return [
|
|
12246
|
+
/* prefix path */ path.slice(0, path.length - 2),
|
|
12247
|
+
/* collection id */ path[path.length - 2],
|
|
12248
|
+
/* document id */ path[path.length - 1]
|
|
12249
|
+
];
|
|
12250
|
+
}
|
|
12251
|
+
/**
|
|
12252
|
+
* Returns a key that can be used for document lookups via the primary key of
|
|
12253
|
+
* the DbRemoteDocument object store.
|
|
12254
|
+
*/
|
|
12255
|
+
function dbReadTimeKey(documentKey, readTime) {
|
|
12256
|
+
const path = documentKey.path.toArray();
|
|
12257
|
+
return [
|
|
12258
|
+
/* prefix path */ path.slice(0, path.length - 2),
|
|
12259
|
+
/* collection id */ path[path.length - 2],
|
|
12260
|
+
toDbTimestampKey(readTime),
|
|
12261
|
+
/* document id */ path[path.length - 1]
|
|
12262
|
+
];
|
|
12263
|
+
}
|
|
12264
|
+
/**
|
|
12265
|
+
* Returns a key that can be used for document lookups on the
|
|
12266
|
+
* `DbRemoteDocumentDocumentCollectionGroupIndex` index.
|
|
12267
|
+
*/
|
|
12268
|
+
function dbCollectionGroupKey(collectionGroup, offset) {
|
|
12269
|
+
const path = offset.documentKey.path.toArray();
|
|
12270
|
+
return [
|
|
12271
|
+
/* collection id */ collectionGroup,
|
|
12272
|
+
toDbTimestampKey(offset.readTime),
|
|
12273
|
+
/* prefix path */ path.slice(0, path.length - 2),
|
|
12274
|
+
/* document id */ path.length > 0 ? path[path.length - 1] : ''
|
|
12275
|
+
];
|
|
12276
|
+
}
|
|
12277
|
+
/**
|
|
12278
|
+
* Comparator that compares document keys according to the primary key sorting
|
|
12279
|
+
* used by the `DbRemoteDocumentDocument` store (by collection path and then
|
|
12280
|
+
* document ID).
|
|
12281
|
+
*/
|
|
12282
|
+
function dbKeyComparator(l, r) {
|
|
12283
|
+
const cmp = l.path.length - r.path.length;
|
|
12284
|
+
return cmp !== 0 ? cmp : DocumentKey.comparator(l, r);
|
|
12170
12285
|
}
|
|
12171
12286
|
/**
|
|
12172
12287
|
* Schema Version for the Web client:
|
|
@@ -12187,9 +12302,11 @@ function dbKey(docKey) {
|
|
|
12187
12302
|
* 10. Rewrite the canonical IDs to the explicit Protobuf-based format.
|
|
12188
12303
|
* 11. Add bundles and named_queries for bundle support.
|
|
12189
12304
|
* 12. Add document overlays.
|
|
12190
|
-
* 13.
|
|
12305
|
+
* 13. Rewrite the keys of the remote document cache to allow for efficient
|
|
12306
|
+
* document lookup via `getAll()`.
|
|
12307
|
+
* 14. Add indexing support.
|
|
12191
12308
|
*/
|
|
12192
|
-
const SCHEMA_VERSION =
|
|
12309
|
+
const SCHEMA_VERSION = 13;
|
|
12193
12310
|
|
|
12194
12311
|
/**
|
|
12195
12312
|
* @license
|
|
@@ -12225,7 +12342,7 @@ class SchemaConverter {
|
|
|
12225
12342
|
createPrimaryClientStore(db);
|
|
12226
12343
|
createMutationQueue(db);
|
|
12227
12344
|
createQueryCache(db);
|
|
12228
|
-
|
|
12345
|
+
createLegacyRemoteDocumentCache(db);
|
|
12229
12346
|
}
|
|
12230
12347
|
// Migration 2 to populate the targetGlobal object no longer needed since
|
|
12231
12348
|
// migration 3 unconditionally clears it.
|
|
@@ -12274,7 +12391,8 @@ class SchemaConverter {
|
|
|
12274
12391
|
// to the DbRemoteDocument object store itself. Since the previous change
|
|
12275
12392
|
// log only contained transient data, we can drop its object store.
|
|
12276
12393
|
dropRemoteDocumentChangesStore(db);
|
|
12277
|
-
|
|
12394
|
+
// Note: Schema version 9 used to create a read time index for the
|
|
12395
|
+
// RemoteDocumentCache. This is now done with schema version 13.
|
|
12278
12396
|
});
|
|
12279
12397
|
}
|
|
12280
12398
|
if (fromVersion < 10 && toVersion >= 10) {
|
|
@@ -12292,6 +12410,12 @@ class SchemaConverter {
|
|
|
12292
12410
|
});
|
|
12293
12411
|
}
|
|
12294
12412
|
if (fromVersion < 13 && toVersion >= 13) {
|
|
12413
|
+
p = p
|
|
12414
|
+
.next(() => createRemoteDocumentCache(db))
|
|
12415
|
+
.next(() => this.rewriteRemoteDocumentCache(db, simpleDbTransaction))
|
|
12416
|
+
.next(() => db.deleteObjectStore(DbRemoteDocumentStore$1));
|
|
12417
|
+
}
|
|
12418
|
+
if (fromVersion < 14 && toVersion >= 14) {
|
|
12295
12419
|
p = p.next(() => {
|
|
12296
12420
|
createFieldIndex(db);
|
|
12297
12421
|
});
|
|
@@ -12301,7 +12425,7 @@ class SchemaConverter {
|
|
|
12301
12425
|
addDocumentGlobal(txn) {
|
|
12302
12426
|
let byteSize = 0;
|
|
12303
12427
|
return txn
|
|
12304
|
-
.store(DbRemoteDocumentStore)
|
|
12428
|
+
.store(DbRemoteDocumentStore$1)
|
|
12305
12429
|
.iterate((_, doc) => {
|
|
12306
12430
|
byteSize += dbDocumentSize(doc);
|
|
12307
12431
|
})
|
|
@@ -12336,7 +12460,7 @@ class SchemaConverter {
|
|
|
12336
12460
|
*/
|
|
12337
12461
|
ensureSequenceNumbers(txn) {
|
|
12338
12462
|
const documentTargetStore = txn.store(DbTargetDocumentStore);
|
|
12339
|
-
const documentsStore = txn.store(DbRemoteDocumentStore);
|
|
12463
|
+
const documentsStore = txn.store(DbRemoteDocumentStore$1);
|
|
12340
12464
|
const globalTargetStore = txn.store(DbTargetGlobalStore);
|
|
12341
12465
|
return globalTargetStore.get(DbTargetGlobalKey).next(metadata => {
|
|
12342
12466
|
const writeSentinelKey = (path) => {
|
|
@@ -12383,7 +12507,7 @@ class SchemaConverter {
|
|
|
12383
12507
|
};
|
|
12384
12508
|
// Index existing remote documents.
|
|
12385
12509
|
return txn
|
|
12386
|
-
.store(DbRemoteDocumentStore)
|
|
12510
|
+
.store(DbRemoteDocumentStore$1)
|
|
12387
12511
|
.iterate({ keysOnly: true }, (pathSegments, _) => {
|
|
12388
12512
|
const path = new ResourcePath(pathSegments);
|
|
12389
12513
|
return addEntry(path.popLast());
|
|
@@ -12406,6 +12530,27 @@ class SchemaConverter {
|
|
|
12406
12530
|
return targetStore.put(updatedDbTarget);
|
|
12407
12531
|
});
|
|
12408
12532
|
}
|
|
12533
|
+
rewriteRemoteDocumentCache(db, transaction) {
|
|
12534
|
+
const legacyRemoteDocumentStore = transaction.store(DbRemoteDocumentStore$1);
|
|
12535
|
+
const writes = [];
|
|
12536
|
+
return legacyRemoteDocumentStore
|
|
12537
|
+
.iterate((_, legacyDocument) => {
|
|
12538
|
+
const remoteDocumentStore = transaction.store(DbRemoteDocumentStore);
|
|
12539
|
+
const path = extractKey(legacyDocument).path.toArray();
|
|
12540
|
+
const dbRemoteDocument = {
|
|
12541
|
+
prefixPath: path.slice(0, path.length - 2),
|
|
12542
|
+
collectionGroup: path[path.length - 2],
|
|
12543
|
+
documentId: path[path.length - 1],
|
|
12544
|
+
readTime: legacyDocument.readTime || [0, 0],
|
|
12545
|
+
unknownDocument: legacyDocument.unknownDocument,
|
|
12546
|
+
noDocument: legacyDocument.noDocument,
|
|
12547
|
+
document: legacyDocument.document,
|
|
12548
|
+
hasCommittedMutations: !!legacyDocument.hasCommittedMutations
|
|
12549
|
+
};
|
|
12550
|
+
writes.push(remoteDocumentStore.put(dbRemoteDocument));
|
|
12551
|
+
})
|
|
12552
|
+
.next(() => PersistencePromise.waitFor(writes));
|
|
12553
|
+
}
|
|
12409
12554
|
}
|
|
12410
12555
|
function sentinelKey(path) {
|
|
12411
12556
|
return [0, encodeResourcePath(path)];
|
|
@@ -12442,8 +12587,15 @@ function upgradeMutationBatchSchemaAndMigrateData(db, txn) {
|
|
|
12442
12587
|
return PersistencePromise.waitFor(writeAll);
|
|
12443
12588
|
});
|
|
12444
12589
|
}
|
|
12590
|
+
function createLegacyRemoteDocumentCache(db) {
|
|
12591
|
+
db.createObjectStore(DbRemoteDocumentStore$1);
|
|
12592
|
+
}
|
|
12445
12593
|
function createRemoteDocumentCache(db) {
|
|
12446
|
-
db.createObjectStore(DbRemoteDocumentStore
|
|
12594
|
+
const remoteDocumentStore = db.createObjectStore(DbRemoteDocumentStore, {
|
|
12595
|
+
keyPath: DbRemoteDocumentKeyPath
|
|
12596
|
+
});
|
|
12597
|
+
remoteDocumentStore.createIndex(DbRemoteDocumentDocumentKeyIndex, DbRemoteDocumentDocumentKeyIndexPath);
|
|
12598
|
+
remoteDocumentStore.createIndex(DbRemoteDocumentCollectionGroupIndex, DbRemoteDocumentCollectionGroupIndexPath);
|
|
12447
12599
|
}
|
|
12448
12600
|
function createDocumentGlobalStore(db) {
|
|
12449
12601
|
db.createObjectStore(DbRemoteDocumentGlobalStore);
|
|
@@ -12485,15 +12637,6 @@ function writeEmptyTargetGlobalEntry(txn) {
|
|
|
12485
12637
|
};
|
|
12486
12638
|
return globalStore.put(DbTargetGlobalKey, metadata);
|
|
12487
12639
|
}
|
|
12488
|
-
/**
|
|
12489
|
-
* Creates indices on the RemoteDocuments store used for both multi-tab
|
|
12490
|
-
* and Index-Free queries.
|
|
12491
|
-
*/
|
|
12492
|
-
function createRemoteDocumentReadTimeIndex(txn) {
|
|
12493
|
-
const remoteDocumentStore = txn.objectStore(DbRemoteDocumentStore);
|
|
12494
|
-
remoteDocumentStore.createIndex(DbRemoteDocumentReadTimeIndex, DbRemoteDocumentReadTimeIndexPath, { unique: false });
|
|
12495
|
-
remoteDocumentStore.createIndex(DbRemoteDocumentCollectionReadTimeIndex, DbRemoteDocumentCollectionReadTimeIndexPath, { unique: false });
|
|
12496
|
-
}
|
|
12497
12640
|
function createClientMetadataStore(db) {
|
|
12498
12641
|
db.createObjectStore(DbClientMetadataStore, {
|
|
12499
12642
|
keyPath: DbClientMetadataKeyPath
|
|
@@ -12510,11 +12653,11 @@ function createNamedQueriesStore(db) {
|
|
|
12510
12653
|
});
|
|
12511
12654
|
}
|
|
12512
12655
|
function createFieldIndex(db) {
|
|
12513
|
-
const
|
|
12656
|
+
const indexConfigurationStore = db.createObjectStore(DbIndexConfigurationStore, {
|
|
12514
12657
|
keyPath: DbIndexConfigurationKeyPath,
|
|
12515
12658
|
autoIncrement: true
|
|
12516
12659
|
});
|
|
12517
|
-
|
|
12660
|
+
indexConfigurationStore.createIndex(DbIndexConfigurationCollectionGroupIndex, DbIndexConfigurationCollectionGroupIndexPath, { unique: false });
|
|
12518
12661
|
const indexStateStore = db.createObjectStore(DbIndexStateStore, {
|
|
12519
12662
|
keyPath: DbIndexStateKeyPath
|
|
12520
12663
|
});
|
|
@@ -12530,6 +12673,20 @@ function createDocumentOverlayStore(db) {
|
|
|
12530
12673
|
});
|
|
12531
12674
|
documentOverlayStore.createIndex(DbDocumentOverlayCollectionPathOverlayIndex, DbDocumentOverlayCollectionPathOverlayIndexPath, { unique: false });
|
|
12532
12675
|
documentOverlayStore.createIndex(DbDocumentOverlayCollectionGroupOverlayIndex, DbDocumentOverlayCollectionGroupOverlayIndexPath, { unique: false });
|
|
12676
|
+
}
|
|
12677
|
+
function extractKey(remoteDoc) {
|
|
12678
|
+
if (remoteDoc.document) {
|
|
12679
|
+
return new DocumentKey(ResourcePath.fromString(remoteDoc.document.name).popFirst(5));
|
|
12680
|
+
}
|
|
12681
|
+
else if (remoteDoc.noDocument) {
|
|
12682
|
+
return DocumentKey.fromSegments(remoteDoc.noDocument.path);
|
|
12683
|
+
}
|
|
12684
|
+
else if (remoteDoc.unknownDocument) {
|
|
12685
|
+
return DocumentKey.fromSegments(remoteDoc.unknownDocument.path);
|
|
12686
|
+
}
|
|
12687
|
+
else {
|
|
12688
|
+
return fail();
|
|
12689
|
+
}
|
|
12533
12690
|
}
|
|
12534
12691
|
|
|
12535
12692
|
/**
|
|
@@ -13372,18 +13529,17 @@ class LocalDocumentsView {
|
|
|
13372
13529
|
*
|
|
13373
13530
|
* @param transaction - The persistence transaction.
|
|
13374
13531
|
* @param query - The query to match documents against.
|
|
13375
|
-
* @param
|
|
13376
|
-
* documents that have been read since this snapshot version (exclusive).
|
|
13532
|
+
* @param offset - Read time and key to start scanning by (exclusive).
|
|
13377
13533
|
*/
|
|
13378
|
-
getDocumentsMatchingQuery(transaction, query,
|
|
13534
|
+
getDocumentsMatchingQuery(transaction, query, offset) {
|
|
13379
13535
|
if (isDocumentQuery$1(query)) {
|
|
13380
13536
|
return this.getDocumentsMatchingDocumentQuery(transaction, query.path);
|
|
13381
13537
|
}
|
|
13382
13538
|
else if (isCollectionGroupQuery(query)) {
|
|
13383
|
-
return this.getDocumentsMatchingCollectionGroupQuery(transaction, query,
|
|
13539
|
+
return this.getDocumentsMatchingCollectionGroupQuery(transaction, query, offset);
|
|
13384
13540
|
}
|
|
13385
13541
|
else {
|
|
13386
|
-
return this.getDocumentsMatchingCollectionQuery(transaction, query,
|
|
13542
|
+
return this.getDocumentsMatchingCollectionQuery(transaction, query, offset);
|
|
13387
13543
|
}
|
|
13388
13544
|
}
|
|
13389
13545
|
getDocumentsMatchingDocumentQuery(transaction, docPath) {
|
|
@@ -13396,7 +13552,7 @@ class LocalDocumentsView {
|
|
|
13396
13552
|
return result;
|
|
13397
13553
|
});
|
|
13398
13554
|
}
|
|
13399
|
-
getDocumentsMatchingCollectionGroupQuery(transaction, query,
|
|
13555
|
+
getDocumentsMatchingCollectionGroupQuery(transaction, query, offset) {
|
|
13400
13556
|
const collectionId = query.collectionGroup;
|
|
13401
13557
|
let results = documentMap();
|
|
13402
13558
|
return this.indexManager
|
|
@@ -13406,7 +13562,7 @@ class LocalDocumentsView {
|
|
|
13406
13562
|
// collectionId and aggregate the results.
|
|
13407
13563
|
return PersistencePromise.forEach(parents, (parent) => {
|
|
13408
13564
|
const collectionQuery = asCollectionQueryAtPath(query, parent.child(collectionId));
|
|
13409
|
-
return this.getDocumentsMatchingCollectionQuery(transaction, collectionQuery,
|
|
13565
|
+
return this.getDocumentsMatchingCollectionQuery(transaction, collectionQuery, offset).next(r => {
|
|
13410
13566
|
r.forEach((key, doc) => {
|
|
13411
13567
|
results = results.insert(key, doc);
|
|
13412
13568
|
});
|
|
@@ -13414,11 +13570,11 @@ class LocalDocumentsView {
|
|
|
13414
13570
|
}).next(() => results);
|
|
13415
13571
|
});
|
|
13416
13572
|
}
|
|
13417
|
-
getDocumentsMatchingCollectionQuery(transaction, query,
|
|
13573
|
+
getDocumentsMatchingCollectionQuery(transaction, query, offset) {
|
|
13418
13574
|
// Query the remote documents and overlay mutations.
|
|
13419
13575
|
let results;
|
|
13420
13576
|
return this.remoteDocumentCache
|
|
13421
|
-
.
|
|
13577
|
+
.getAllFromCollection(transaction, query.path, offset)
|
|
13422
13578
|
.next(queryResults => {
|
|
13423
13579
|
results = queryResults;
|
|
13424
13580
|
return this.mutationQueue.getAllMutationBatchesAffectingQuery(transaction, query);
|
|
@@ -13504,11 +13660,12 @@ class LocalStoreImpl {
|
|
|
13504
13660
|
// TODO(wuandy): Evaluate if TargetId can be part of Target.
|
|
13505
13661
|
this.targetIdByTarget = new ObjectMap(t => canonifyTarget(t), targetEquals);
|
|
13506
13662
|
/**
|
|
13507
|
-
*
|
|
13663
|
+
* A per collection group index of the last read time processed by
|
|
13664
|
+
* `getNewDocumentChanges()`.
|
|
13508
13665
|
*
|
|
13509
13666
|
* PORTING NOTE: This is only used for multi-tab synchronization.
|
|
13510
13667
|
*/
|
|
13511
|
-
this.
|
|
13668
|
+
this.collectionGroupReadTime = new Map();
|
|
13512
13669
|
this.remoteDocuments = persistence.getRemoteDocumentCache();
|
|
13513
13670
|
this.targetCache = persistence.getTargetCache();
|
|
13514
13671
|
this.bundleCache = persistence.getBundleCache();
|
|
@@ -14043,6 +14200,7 @@ function localStoreExecuteQuery(localStore, query, usePreviousResults) {
|
|
|
14043
14200
|
? lastLimboFreeSnapshotVersion
|
|
14044
14201
|
: SnapshotVersion.min(), usePreviousResults ? remoteKeys : documentKeySet()))
|
|
14045
14202
|
.next(documents => {
|
|
14203
|
+
setMaxReadTime(localStoreImpl, queryCollectionGroup(query), documents);
|
|
14046
14204
|
return { documents, remoteKeys };
|
|
14047
14205
|
});
|
|
14048
14206
|
});
|
|
@@ -14120,28 +14278,32 @@ function localStoreGetCachedTarget(localStore, targetId) {
|
|
|
14120
14278
|
* since the prior call.
|
|
14121
14279
|
*/
|
|
14122
14280
|
// PORTING NOTE: Multi-Tab only.
|
|
14123
|
-
function localStoreGetNewDocumentChanges(localStore) {
|
|
14281
|
+
function localStoreGetNewDocumentChanges(localStore, collectionGroup) {
|
|
14124
14282
|
const localStoreImpl = debugCast(localStore);
|
|
14283
|
+
// Get the current maximum read time for the collection. This should always
|
|
14284
|
+
// exist, but to reduce the chance for regressions we default to
|
|
14285
|
+
// SnapshotVersion.Min()
|
|
14286
|
+
// TODO(indexing): Consider removing the default value.
|
|
14287
|
+
const readTime = localStoreImpl.collectionGroupReadTime.get(collectionGroup) ||
|
|
14288
|
+
SnapshotVersion.min();
|
|
14125
14289
|
return localStoreImpl.persistence
|
|
14126
|
-
.runTransaction('Get new document changes', 'readonly', txn =>
|
|
14127
|
-
|
|
14128
|
-
|
|
14290
|
+
.runTransaction('Get new document changes', 'readonly', txn => localStoreImpl.remoteDocuments.getAllFromCollectionGroup(txn, collectionGroup, newIndexOffsetSuccessorFromReadTime(readTime, INITIAL_LARGEST_BATCH_ID),
|
|
14291
|
+
/* limit= */ Number.MAX_SAFE_INTEGER))
|
|
14292
|
+
.then(changedDocs => {
|
|
14293
|
+
setMaxReadTime(localStoreImpl, collectionGroup, changedDocs);
|
|
14129
14294
|
return changedDocs;
|
|
14130
14295
|
});
|
|
14131
14296
|
}
|
|
14132
|
-
/**
|
|
14133
|
-
* Reads the newest document change from persistence and moves the internal
|
|
14134
|
-
* synchronization marker forward so that calls to `getNewDocumentChanges()`
|
|
14135
|
-
* only return changes that happened after client initialization.
|
|
14136
|
-
*/
|
|
14297
|
+
/** Sets the collection group's maximum read time from the given documents. */
|
|
14137
14298
|
// PORTING NOTE: Multi-Tab only.
|
|
14138
|
-
|
|
14139
|
-
|
|
14140
|
-
|
|
14141
|
-
.
|
|
14142
|
-
|
|
14143
|
-
|
|
14299
|
+
function setMaxReadTime(localStoreImpl, collectionGroup, changedDocs) {
|
|
14300
|
+
let readTime = SnapshotVersion.min();
|
|
14301
|
+
changedDocs.forEach((_, doc) => {
|
|
14302
|
+
if (doc.readTime.compareTo(readTime) > 0) {
|
|
14303
|
+
readTime = doc.readTime;
|
|
14304
|
+
}
|
|
14144
14305
|
});
|
|
14306
|
+
localStoreImpl.collectionGroupReadTime.set(collectionGroup, readTime);
|
|
14145
14307
|
}
|
|
14146
14308
|
/**
|
|
14147
14309
|
* Creates a new target using the given bundle name, which will be used to
|
|
@@ -14824,7 +14986,7 @@ class MemoryRemoteDocumentCacheImpl {
|
|
|
14824
14986
|
});
|
|
14825
14987
|
return PersistencePromise.resolve(results);
|
|
14826
14988
|
}
|
|
14827
|
-
|
|
14989
|
+
getAllFromCollection(transaction, collectionPath, offset) {
|
|
14828
14990
|
let results = mutableDocumentMap();
|
|
14829
14991
|
// Documents are ordered by key, so we can use a prefix scan to narrow down
|
|
14830
14992
|
// the documents we need to match the query against.
|
|
@@ -14839,13 +15001,19 @@ class MemoryRemoteDocumentCacheImpl {
|
|
|
14839
15001
|
// Exclude entries from subcollections.
|
|
14840
15002
|
continue;
|
|
14841
15003
|
}
|
|
14842
|
-
if (document
|
|
15004
|
+
if (indexOffsetComparator(newIndexOffsetFromDocument(document), offset) <= 0) {
|
|
15005
|
+
// The document sorts before the offset.
|
|
14843
15006
|
continue;
|
|
14844
15007
|
}
|
|
14845
15008
|
results = results.insert(document.key, document.mutableCopy());
|
|
14846
15009
|
}
|
|
14847
15010
|
return PersistencePromise.resolve(results);
|
|
14848
15011
|
}
|
|
15012
|
+
getAllFromCollectionGroup(transaction, collectionGroup, offset, limti) {
|
|
15013
|
+
// This method should only be called from the IndexBackfiller if persistence
|
|
15014
|
+
// is enabled.
|
|
15015
|
+
fail();
|
|
15016
|
+
}
|
|
14849
15017
|
forEachDocumentKey(transaction, f) {
|
|
14850
15018
|
return PersistencePromise.forEach(this.docs, (key) => f(key));
|
|
14851
15019
|
}
|
|
@@ -15298,7 +15466,7 @@ class QueryEngine {
|
|
|
15298
15466
|
}
|
|
15299
15467
|
// Retrieve all results for documents that were updated since the last
|
|
15300
15468
|
// limbo-document free remote snapshot.
|
|
15301
|
-
return this.localDocumentsView.getDocumentsMatchingQuery(transaction, query, lastLimboFreeSnapshotVersion).next(updatedResults => {
|
|
15469
|
+
return this.localDocumentsView.getDocumentsMatchingQuery(transaction, query, newIndexOffsetSuccessorFromReadTime(lastLimboFreeSnapshotVersion, INITIAL_LARGEST_BATCH_ID)).next(updatedResults => {
|
|
15302
15470
|
// We merge `previousResults` into `updateResults`, since
|
|
15303
15471
|
// `updateResults` is already a DocumentMap. If a document is
|
|
15304
15472
|
// contained in both lists, then its contents are the same.
|
|
@@ -15360,7 +15528,7 @@ class QueryEngine {
|
|
|
15360
15528
|
if (getLogLevel() <= logger.LogLevel.DEBUG) {
|
|
15361
15529
|
logDebug('QueryEngine', 'Using full collection scan to execute query:', stringifyQuery(query));
|
|
15362
15530
|
}
|
|
15363
|
-
return this.localDocumentsView.getDocumentsMatchingQuery(transaction, query,
|
|
15531
|
+
return this.localDocumentsView.getDocumentsMatchingQuery(transaction, query, IndexOffset.min());
|
|
15364
15532
|
}
|
|
15365
15533
|
}
|
|
15366
15534
|
|
|
@@ -15421,8 +15589,9 @@ function createWebStorageOnlineStateKey(persistenceKey) {
|
|
|
15421
15589
|
// The WebStorage prefix that plays as a event to indicate the remote documents
|
|
15422
15590
|
// might have changed due to some secondary tabs loading a bundle.
|
|
15423
15591
|
// format of the key is:
|
|
15424
|
-
//
|
|
15425
|
-
|
|
15592
|
+
// firestore_bundle_loaded_v2_<persistenceKey>
|
|
15593
|
+
// The version ending with "v2" stores the list of modified collection groups.
|
|
15594
|
+
const BUNDLE_LOADED_KEY_PREFIX = 'firestore_bundle_loaded_v2';
|
|
15426
15595
|
function createBundleLoadedKey(persistenceKey) {
|
|
15427
15596
|
return `${BUNDLE_LOADED_KEY_PREFIX}_${persistenceKey}`;
|
|
15428
15597
|
}
|
|
@@ -15800,8 +15969,8 @@ class WebStorageSharedClientState {
|
|
|
15800
15969
|
setOnlineState(onlineState) {
|
|
15801
15970
|
this.persistOnlineState(onlineState);
|
|
15802
15971
|
}
|
|
15803
|
-
notifyBundleLoaded() {
|
|
15804
|
-
this.persistBundleLoadedState();
|
|
15972
|
+
notifyBundleLoaded(collectionGroups) {
|
|
15973
|
+
this.persistBundleLoadedState(collectionGroups);
|
|
15805
15974
|
}
|
|
15806
15975
|
shutdown() {
|
|
15807
15976
|
if (this.started) {
|
|
@@ -15885,7 +16054,8 @@ class WebStorageSharedClientState {
|
|
|
15885
16054
|
}
|
|
15886
16055
|
}
|
|
15887
16056
|
else if (storageEvent.key === this.bundleLoadedKey) {
|
|
15888
|
-
|
|
16057
|
+
const collectionGroups = this.fromWebStoreBundleLoadedState(storageEvent.newValue);
|
|
16058
|
+
await Promise.all(collectionGroups.map(cg => this.syncEngine.synchronizeWithChangedDocuments(cg)));
|
|
15889
16059
|
}
|
|
15890
16060
|
});
|
|
15891
16061
|
}
|
|
@@ -15917,8 +16087,9 @@ class WebStorageSharedClientState {
|
|
|
15917
16087
|
const targetMetadata = new QueryTargetMetadata(targetId, state, error);
|
|
15918
16088
|
this.setItem(targetKey, targetMetadata.toWebStorageJSON());
|
|
15919
16089
|
}
|
|
15920
|
-
persistBundleLoadedState() {
|
|
15921
|
-
|
|
16090
|
+
persistBundleLoadedState(collectionGroups) {
|
|
16091
|
+
const json = JSON.stringify(Array.from(collectionGroups));
|
|
16092
|
+
this.setItem(this.bundleLoadedKey, json);
|
|
15922
16093
|
}
|
|
15923
16094
|
/**
|
|
15924
16095
|
* Parses a client state key in WebStorage. Returns null if the key does not
|
|
@@ -15962,6 +16133,9 @@ class WebStorageSharedClientState {
|
|
|
15962
16133
|
fromWebStorageOnlineState(value) {
|
|
15963
16134
|
return SharedOnlineState.fromWebStorageEntry(value);
|
|
15964
16135
|
}
|
|
16136
|
+
fromWebStoreBundleLoadedState(value) {
|
|
16137
|
+
return JSON.parse(value);
|
|
16138
|
+
}
|
|
15965
16139
|
async handleMutationBatchEvent(mutationBatch) {
|
|
15966
16140
|
if (mutationBatch.user.uid !== this.currentUser.uid) {
|
|
15967
16141
|
logDebug(LOG_TAG$a, `Ignoring mutation for non-active user ${mutationBatch.user.uid}`);
|
|
@@ -16078,7 +16252,7 @@ class MemorySharedClientState {
|
|
|
16078
16252
|
}
|
|
16079
16253
|
shutdown() { }
|
|
16080
16254
|
writeSequenceNumber(sequenceNumber) { }
|
|
16081
|
-
notifyBundleLoaded() {
|
|
16255
|
+
notifyBundleLoaded(collectionGroups) {
|
|
16082
16256
|
// No op.
|
|
16083
16257
|
}
|
|
16084
16258
|
}
|
|
@@ -21378,29 +21552,6 @@ class LocalViewChanges {
|
|
|
21378
21552
|
}
|
|
21379
21553
|
}
|
|
21380
21554
|
|
|
21381
|
-
/**
|
|
21382
|
-
* @license
|
|
21383
|
-
* Copyright 2020 Google LLC
|
|
21384
|
-
*
|
|
21385
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
21386
|
-
* you may not use this file except in compliance with the License.
|
|
21387
|
-
* You may obtain a copy of the License at
|
|
21388
|
-
*
|
|
21389
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
21390
|
-
*
|
|
21391
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
21392
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
21393
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
21394
|
-
* See the License for the specific language governing permissions and
|
|
21395
|
-
* limitations under the License.
|
|
21396
|
-
*/
|
|
21397
|
-
class BundleLoadResult {
|
|
21398
|
-
constructor(progress, changedDocs) {
|
|
21399
|
-
this.progress = progress;
|
|
21400
|
-
this.changedDocs = changedDocs;
|
|
21401
|
-
}
|
|
21402
|
-
}
|
|
21403
|
-
|
|
21404
21555
|
/**
|
|
21405
21556
|
* @license
|
|
21406
21557
|
* Copyright 2020 Google LLC
|
|
@@ -21455,6 +21606,8 @@ class BundleLoader {
|
|
|
21455
21606
|
this.queries = [];
|
|
21456
21607
|
/** Batched documents to be saved into storage */
|
|
21457
21608
|
this.documents = [];
|
|
21609
|
+
/** The collection groups affected by this bundle. */
|
|
21610
|
+
this.collectionGroups = new Set();
|
|
21458
21611
|
this.progress = bundleInitialProgress(bundleMetadata);
|
|
21459
21612
|
}
|
|
21460
21613
|
/**
|
|
@@ -21474,6 +21627,8 @@ class BundleLoader {
|
|
|
21474
21627
|
if (!element.payload.documentMetadata.exists) {
|
|
21475
21628
|
++documentsLoaded;
|
|
21476
21629
|
}
|
|
21630
|
+
const path = ResourcePath.fromString(element.payload.documentMetadata.name);
|
|
21631
|
+
this.collectionGroups.add(path.get(path.length - 2));
|
|
21477
21632
|
}
|
|
21478
21633
|
else if (element.payload.document) {
|
|
21479
21634
|
this.documents[this.documents.length - 1].document =
|
|
@@ -21504,13 +21659,17 @@ class BundleLoader {
|
|
|
21504
21659
|
* Update the progress to 'Success' and return the updated progress.
|
|
21505
21660
|
*/
|
|
21506
21661
|
async complete() {
|
|
21507
|
-
const
|
|
21662
|
+
const changedDocs = await localStoreApplyBundledDocuments(this.localStore, new BundleConverterImpl(this.serializer), this.documents, this.bundleMetadata.id);
|
|
21508
21663
|
const queryDocumentMap = this.getQueryDocumentMapping(this.documents);
|
|
21509
21664
|
for (const q of this.queries) {
|
|
21510
21665
|
await localStoreSaveNamedQuery(this.localStore, q, queryDocumentMap.get(q.name));
|
|
21511
21666
|
}
|
|
21512
21667
|
this.progress.taskState = 'Success';
|
|
21513
|
-
return
|
|
21668
|
+
return {
|
|
21669
|
+
progress: this.progress,
|
|
21670
|
+
changedCollectionGroups: this.collectionGroups,
|
|
21671
|
+
changedDocs
|
|
21672
|
+
};
|
|
21514
21673
|
}
|
|
21515
21674
|
}
|
|
21516
21675
|
/**
|
|
@@ -22589,9 +22748,9 @@ async function synchronizeViewAndComputeSnapshot(syncEngine, queryView) {
|
|
|
22589
22748
|
* snapshots if needed.
|
|
22590
22749
|
*/
|
|
22591
22750
|
// PORTING NOTE: Multi-Tab only.
|
|
22592
|
-
async function syncEngineSynchronizeWithChangedDocuments(syncEngine) {
|
|
22751
|
+
async function syncEngineSynchronizeWithChangedDocuments(syncEngine, collectionGroup) {
|
|
22593
22752
|
const syncEngineImpl = debugCast(syncEngine);
|
|
22594
|
-
return localStoreGetNewDocumentChanges(syncEngineImpl.localStore).then(changes => syncEngineEmitNewSnapsAndNotifyLocalStore(syncEngineImpl, changes));
|
|
22753
|
+
return localStoreGetNewDocumentChanges(syncEngineImpl.localStore, collectionGroup).then(changes => syncEngineEmitNewSnapsAndNotifyLocalStore(syncEngineImpl, changes));
|
|
22595
22754
|
}
|
|
22596
22755
|
/** Applies a mutation state to an existing batch. */
|
|
22597
22756
|
// PORTING NOTE: Multi-Tab only.
|
|
@@ -22756,11 +22915,12 @@ async function syncEngineApplyTargetState(syncEngine, targetId, state, error) {
|
|
|
22756
22915
|
logDebug(LOG_TAG$3, 'Ignoring unexpected query state notification.');
|
|
22757
22916
|
return;
|
|
22758
22917
|
}
|
|
22759
|
-
|
|
22918
|
+
const query = syncEngineImpl.queriesByTarget.get(targetId);
|
|
22919
|
+
if (query && query.length > 0) {
|
|
22760
22920
|
switch (state) {
|
|
22761
22921
|
case 'current':
|
|
22762
22922
|
case 'not-current': {
|
|
22763
|
-
const changes = await localStoreGetNewDocumentChanges(syncEngineImpl.localStore);
|
|
22923
|
+
const changes = await localStoreGetNewDocumentChanges(syncEngineImpl.localStore, queryCollectionGroup(query[0]));
|
|
22764
22924
|
const synthesizedRemoteEvent = RemoteEvent.createSynthesizedRemoteEventForCurrentChange(targetId, state === 'current');
|
|
22765
22925
|
await syncEngineEmitNewSnapsAndNotifyLocalStore(syncEngineImpl, changes, synthesizedRemoteEvent);
|
|
22766
22926
|
break;
|
|
@@ -22843,10 +23003,11 @@ function syncEngineEnsureWriteCallbacks(syncEngine) {
|
|
|
22843
23003
|
function syncEngineLoadBundle(syncEngine, bundleReader, task) {
|
|
22844
23004
|
const syncEngineImpl = debugCast(syncEngine);
|
|
22845
23005
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
22846
|
-
loadBundleImpl(syncEngineImpl, bundleReader, task).then(
|
|
22847
|
-
syncEngineImpl.sharedClientState.notifyBundleLoaded();
|
|
23006
|
+
loadBundleImpl(syncEngineImpl, bundleReader, task).then(collectionGroups => {
|
|
23007
|
+
syncEngineImpl.sharedClientState.notifyBundleLoaded(collectionGroups);
|
|
22848
23008
|
});
|
|
22849
23009
|
}
|
|
23010
|
+
/** Loads a bundle and returns the list of affected collection groups. */
|
|
22850
23011
|
async function loadBundleImpl(syncEngine, reader, task) {
|
|
22851
23012
|
try {
|
|
22852
23013
|
const metadata = await reader.getMetadata();
|
|
@@ -22854,7 +23015,7 @@ async function loadBundleImpl(syncEngine, reader, task) {
|
|
|
22854
23015
|
if (skip) {
|
|
22855
23016
|
await reader.close();
|
|
22856
23017
|
task._completeWith(bundleSuccessProgress(metadata));
|
|
22857
|
-
return;
|
|
23018
|
+
return Promise.resolve(new Set());
|
|
22858
23019
|
}
|
|
22859
23020
|
task._updateProgress(bundleInitialProgress(metadata));
|
|
22860
23021
|
const loader = new BundleLoader(metadata, syncEngine.localStore, reader.serializer);
|
|
@@ -22868,18 +23029,17 @@ async function loadBundleImpl(syncEngine, reader, task) {
|
|
|
22868
23029
|
element = await reader.nextElement();
|
|
22869
23030
|
}
|
|
22870
23031
|
const result = await loader.complete();
|
|
22871
|
-
// TODO(b/160876443): This currently raises snapshots with
|
|
22872
|
-
// `fromCache=false` if users already listen to some queries and bundles
|
|
22873
|
-
// has newer version.
|
|
22874
23032
|
await syncEngineEmitNewSnapsAndNotifyLocalStore(syncEngine, result.changedDocs,
|
|
22875
23033
|
/* remoteEvent */ undefined);
|
|
22876
23034
|
// Save metadata, so loading the same bundle will skip.
|
|
22877
23035
|
await localStoreSaveBundle(syncEngine.localStore, metadata);
|
|
22878
23036
|
task._completeWith(result.progress);
|
|
23037
|
+
return Promise.resolve(result.changedCollectionGroups);
|
|
22879
23038
|
}
|
|
22880
23039
|
catch (e) {
|
|
22881
23040
|
logWarn(LOG_TAG$3, `Loading bundle failed with ${e}`);
|
|
22882
23041
|
task._failWith(e);
|
|
23042
|
+
return Promise.resolve(new Set());
|
|
22883
23043
|
}
|
|
22884
23044
|
}
|
|
22885
23045
|
|
|
@@ -22948,7 +23108,6 @@ class IndexedDbOfflineComponentProvider extends MemoryOfflineComponentProvider {
|
|
|
22948
23108
|
}
|
|
22949
23109
|
async initialize(cfg) {
|
|
22950
23110
|
await super.initialize(cfg);
|
|
22951
|
-
await localStoreSynchronizeLastDocumentChangeReadTime(this.localStore);
|
|
22952
23111
|
await this.onlineComponentProvider.initialize(this, cfg);
|
|
22953
23112
|
// Enqueue writes from a previous session
|
|
22954
23113
|
await syncEngineEnsureWriteCallbacks(this.onlineComponentProvider.syncEngine);
|