@firebase/firestore 3.4.5-canary.2b98b28f2 → 3.4.5-canary.2d672cead

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.
Files changed (66) hide show
  1. package/dist/firestore/src/local/document_overlay_cache.d.ts +4 -5
  2. package/dist/firestore/src/local/indexeddb_document_overlay_cache.d.ts +4 -5
  3. package/dist/firestore/src/local/indexeddb_index_manager.d.ts +1 -1
  4. package/dist/firestore/src/local/indexeddb_schema.d.ts +34 -553
  5. package/dist/firestore/src/local/indexeddb_sentinels.d.ts +238 -0
  6. package/dist/firestore/src/local/indexeddb_target_cache.d.ts +2 -1
  7. package/dist/firestore/src/local/local_serializer.d.ts +2 -1
  8. package/dist/firestore/src/local/memory_document_overlay_cache.d.ts +4 -5
  9. package/dist/firestore/src/model/collections.d.ts +7 -0
  10. package/dist/firestore/src/util/obj_map.d.ts +3 -0
  11. package/dist/firestore/test/unit/local/test_document_overlay_cache.d.ts +4 -4
  12. package/dist/index.esm2017.js +3143 -3655
  13. package/dist/index.esm2017.js.map +1 -1
  14. package/dist/index.esm5.js +3305 -3756
  15. package/dist/index.esm5.js.map +1 -1
  16. package/dist/index.node.cjs.js +483 -929
  17. package/dist/index.node.cjs.js.map +1 -1
  18. package/dist/index.node.mjs +483 -929
  19. package/dist/index.node.mjs.map +1 -1
  20. package/dist/index.rn.js +3168 -3680
  21. package/dist/index.rn.js.map +1 -1
  22. package/dist/internal.d.ts +10 -3
  23. package/dist/lite/firestore/src/local/document_overlay_cache.d.ts +4 -5
  24. package/dist/lite/firestore/src/local/indexeddb_document_overlay_cache.d.ts +4 -5
  25. package/dist/lite/firestore/src/local/indexeddb_index_manager.d.ts +1 -1
  26. package/dist/lite/firestore/src/local/indexeddb_schema.d.ts +34 -553
  27. package/dist/lite/firestore/src/local/indexeddb_sentinels.d.ts +238 -0
  28. package/dist/lite/firestore/src/local/indexeddb_target_cache.d.ts +2 -1
  29. package/dist/lite/firestore/src/local/local_serializer.d.ts +2 -1
  30. package/dist/lite/firestore/src/local/memory_document_overlay_cache.d.ts +4 -5
  31. package/dist/lite/firestore/src/model/collections.d.ts +7 -0
  32. package/dist/lite/firestore/src/util/obj_map.d.ts +3 -0
  33. package/dist/lite/firestore/test/unit/local/test_document_overlay_cache.d.ts +4 -4
  34. package/dist/lite/index.browser.esm2017.js +72 -72
  35. package/dist/lite/index.browser.esm2017.js.map +1 -1
  36. package/dist/lite/index.browser.esm5.js +8 -8
  37. package/dist/lite/index.node.cjs.js +2 -2
  38. package/dist/lite/index.node.mjs +2 -2
  39. package/dist/lite/index.node.mjs.map +1 -1
  40. package/dist/lite/index.rn.esm2017.js +83 -83
  41. package/dist/lite/packages/firestore/dist/lite/index.browser.esm2017.d.ts +18 -18
  42. package/dist/lite/packages/firestore/src/local/document_overlay_cache.d.ts +4 -5
  43. package/dist/lite/packages/firestore/src/local/indexeddb_document_overlay_cache.d.ts +4 -5
  44. package/dist/lite/packages/firestore/src/local/indexeddb_index_manager.d.ts +1 -1
  45. package/dist/lite/packages/firestore/src/local/indexeddb_schema.d.ts +34 -553
  46. package/dist/lite/packages/firestore/src/local/indexeddb_sentinels.d.ts +238 -0
  47. package/dist/lite/packages/firestore/src/local/indexeddb_target_cache.d.ts +2 -1
  48. package/dist/lite/packages/firestore/src/local/local_serializer.d.ts +2 -1
  49. package/dist/lite/packages/firestore/src/local/memory_document_overlay_cache.d.ts +4 -5
  50. package/dist/lite/packages/firestore/src/model/collections.d.ts +7 -0
  51. package/dist/lite/packages/firestore/src/util/obj_map.d.ts +3 -0
  52. package/dist/lite/packages/firestore/test/unit/local/test_document_overlay_cache.d.ts +4 -4
  53. package/dist/packages/firestore/dist/index.esm2017.d.ts +163 -163
  54. package/dist/packages/firestore/src/local/document_overlay_cache.d.ts +4 -5
  55. package/dist/packages/firestore/src/local/indexeddb_document_overlay_cache.d.ts +4 -5
  56. package/dist/packages/firestore/src/local/indexeddb_index_manager.d.ts +1 -1
  57. package/dist/packages/firestore/src/local/indexeddb_schema.d.ts +34 -553
  58. package/dist/packages/firestore/src/local/indexeddb_sentinels.d.ts +238 -0
  59. package/dist/packages/firestore/src/local/indexeddb_target_cache.d.ts +2 -1
  60. package/dist/packages/firestore/src/local/local_serializer.d.ts +2 -1
  61. package/dist/packages/firestore/src/local/memory_document_overlay_cache.d.ts +4 -5
  62. package/dist/packages/firestore/src/model/collections.d.ts +7 -0
  63. package/dist/packages/firestore/src/util/obj_map.d.ts +3 -0
  64. package/dist/packages/firestore/test/unit/local/test_document_overlay_cache.d.ts +4 -4
  65. package/dist/private.d.ts +10 -3
  66. package/package.json +9 -9
@@ -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.5-canary.2b98b28f2";
36
+ const version$1 = "3.4.5-canary.2d672cead";
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.7-canary.2b98b28f2";
89
+ const version = "9.6.7-canary.2d672cead";
90
90
 
91
91
  /**
92
92
  * @license
@@ -1224,55 +1224,23 @@ function decodeResourcePath(path) {
1224
1224
  }
1225
1225
  return new ResourcePath(segments);
1226
1226
  }
1227
+
1227
1228
  /**
1228
- * Schema Version for the Web client:
1229
- * 1. Initial version including Mutation Queue, Query Cache, and Remote
1230
- * Document Cache
1231
- * 2. Used to ensure a targetGlobal object exists and add targetCount to it. No
1232
- * longer required because migration 3 unconditionally clears it.
1233
- * 3. Dropped and re-created Query Cache to deal with cache corruption related
1234
- * to limbo resolution. Addresses
1235
- * https://github.com/firebase/firebase-ios-sdk/issues/1548
1236
- * 4. Multi-Tab Support.
1237
- * 5. Removal of held write acks.
1238
- * 6. Create document global for tracking document cache size.
1239
- * 7. Ensure every cached document has a sentinel row with a sequence number.
1240
- * 8. Add collection-parent index for Collection Group queries.
1241
- * 9. Change RemoteDocumentChanges store to be keyed by readTime rather than
1242
- * an auto-incrementing ID. This is required for Index-Free queries.
1243
- * 10. Rewrite the canonical IDs to the explicit Protobuf-based format.
1244
- * 11. Add bundles and named_queries for bundle support.
1245
- * 12. Add document overlays.
1246
- * 13. Add indexing support.
1247
- */
1248
- const SCHEMA_VERSION = 12;
1249
- /**
1250
- * Wrapper class to store timestamps (seconds and nanos) in IndexedDb objects.
1251
- */
1252
- class DbTimestamp {
1253
- constructor(seconds, nanoseconds) {
1254
- this.seconds = seconds;
1255
- this.nanoseconds = nanoseconds;
1256
- }
1257
- }
1258
- /**
1259
- * A singleton object to be stored in the 'owner' store in IndexedDb.
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
1260
1237
  *
1261
- * A given database can have a single primary tab assigned at a given time. That
1262
- * tab must validate that it is still holding the primary lease before every
1263
- * operation that requires locked access. The primary tab should regularly
1264
- * write an updated timestamp to this lease to prevent other tabs from
1265
- * "stealing" the primary lease
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.
1266
1243
  */
1267
- class DbPrimaryClient {
1268
- constructor(ownerId,
1269
- /** Whether to allow shared access from multiple tabs. */
1270
- allowTabSynchronization, leaseTimestampMs) {
1271
- this.ownerId = ownerId;
1272
- this.allowTabSynchronization = allowTabSynchronization;
1273
- this.leaseTimestampMs = leaseTimestampMs;
1274
- }
1275
- }
1276
1244
  /**
1277
1245
  * Name of the IndexedDb object store.
1278
1246
  *
@@ -1280,239 +1248,62 @@ class DbPrimaryClient {
1280
1248
  * older clients that only supported single locked access to the persistence
1281
1249
  * layer.
1282
1250
  */
1283
- DbPrimaryClient.store = 'owner';
1251
+ const DbPrimaryClientStore = 'owner';
1284
1252
  /**
1285
1253
  * The key string used for the single object that exists in the
1286
1254
  * DbPrimaryClient store.
1287
1255
  */
1288
- DbPrimaryClient.key = 'owner';
1289
- /**
1290
- * An object to be stored in the 'mutationQueues' store in IndexedDb.
1291
- *
1292
- * Each user gets a single queue of MutationBatches to apply to the server.
1293
- * DbMutationQueue tracks the metadata about the queue.
1294
- */
1295
- class DbMutationQueue {
1296
- constructor(
1297
- /**
1298
- * The normalized user ID to which this queue belongs.
1299
- */
1300
- userId,
1301
- /**
1302
- * An identifier for the highest numbered batch that has been acknowledged
1303
- * by the server. All MutationBatches in this queue with batchIds less
1304
- * than or equal to this value are considered to have been acknowledged by
1305
- * the server.
1306
- *
1307
- * NOTE: this is deprecated and no longer used by the code.
1308
- */
1309
- lastAcknowledgedBatchId,
1310
- /**
1311
- * A stream token that was previously sent by the server.
1312
- *
1313
- * See StreamingWriteRequest in datastore.proto for more details about
1314
- * usage.
1315
- *
1316
- * After sending this token, earlier tokens may not be used anymore so
1317
- * only a single stream token is retained.
1318
- *
1319
- * NOTE: this is deprecated and no longer used by the code.
1320
- */
1321
- lastStreamToken) {
1322
- this.userId = userId;
1323
- this.lastAcknowledgedBatchId = lastAcknowledgedBatchId;
1324
- this.lastStreamToken = lastStreamToken;
1325
- }
1326
- }
1256
+ const DbPrimaryClientKey = 'owner';
1327
1257
  /** Name of the IndexedDb object store. */
1328
- DbMutationQueue.store = 'mutationQueues';
1258
+ const DbMutationQueueStore = 'mutationQueues';
1329
1259
  /** Keys are automatically assigned via the userId property. */
1330
- DbMutationQueue.keyPath = 'userId';
1331
- /**
1332
- * An object to be stored in the 'mutations' store in IndexedDb.
1333
- *
1334
- * Represents a batch of user-level mutations intended to be sent to the server
1335
- * in a single write. Each user-level batch gets a separate DbMutationBatch
1336
- * with a new batchId.
1337
- */
1338
- class DbMutationBatch {
1339
- constructor(
1340
- /**
1341
- * The normalized user ID to which this batch belongs.
1342
- */
1343
- userId,
1344
- /**
1345
- * An identifier for this batch, allocated using an auto-generated key.
1346
- */
1347
- batchId,
1348
- /**
1349
- * The local write time of the batch, stored as milliseconds since the
1350
- * epoch.
1351
- */
1352
- localWriteTimeMs,
1353
- /**
1354
- * A list of "mutations" that represent a partial base state from when this
1355
- * write batch was initially created. During local application of the write
1356
- * batch, these baseMutations are applied prior to the real writes in order
1357
- * to override certain document fields from the remote document cache. This
1358
- * is necessary in the case of non-idempotent writes (e.g. `increment()`
1359
- * transforms) to make sure that the local view of the modified documents
1360
- * doesn't flicker if the remote document cache receives the result of the
1361
- * non-idempotent write before the write is removed from the queue.
1362
- *
1363
- * These mutations are never sent to the backend.
1364
- */
1365
- baseMutations,
1366
- /**
1367
- * A list of mutations to apply. All mutations will be applied atomically.
1368
- *
1369
- * Mutations are serialized via toMutation().
1370
- */
1371
- mutations) {
1372
- this.userId = userId;
1373
- this.batchId = batchId;
1374
- this.localWriteTimeMs = localWriteTimeMs;
1375
- this.baseMutations = baseMutations;
1376
- this.mutations = mutations;
1377
- }
1378
- }
1260
+ const DbMutationQueueKeyPath = 'userId';
1379
1261
  /** Name of the IndexedDb object store. */
1380
- DbMutationBatch.store = 'mutations';
1262
+ const DbMutationBatchStore = 'mutations';
1381
1263
  /** Keys are automatically assigned via the userId, batchId properties. */
1382
- DbMutationBatch.keyPath = 'batchId';
1264
+ const DbMutationBatchKeyPath = 'batchId';
1383
1265
  /** The index name for lookup of mutations by user. */
1384
- DbMutationBatch.userMutationsIndex = 'userMutationsIndex';
1266
+ const DbMutationBatchUserMutationsIndex = 'userMutationsIndex';
1385
1267
  /** The user mutations index is keyed by [userId, batchId] pairs. */
1386
- DbMutationBatch.userMutationsKeyPath = ['userId', 'batchId'];
1268
+ const DbMutationBatchUserMutationsKeyPath = ['userId', 'batchId'];
1387
1269
  /**
1388
- * An object to be stored in the 'documentMutations' store in IndexedDb.
1389
- *
1390
- * A manually maintained index of all the mutation batches that affect a given
1391
- * document key. The rows in this table are references based on the contents of
1392
- * DbMutationBatch.mutations.
1270
+ * Creates a [userId] key for use in the DbDocumentMutations index to iterate
1271
+ * over all of a user's document mutations.
1393
1272
  */
1394
- class DbDocumentMutation {
1395
- constructor() { }
1396
- /**
1397
- * Creates a [userId] key for use in the DbDocumentMutations index to iterate
1398
- * over all of a user's document mutations.
1399
- */
1400
- static prefixForUser(userId) {
1401
- return [userId];
1402
- }
1403
- /**
1404
- * Creates a [userId, encodedPath] key for use in the DbDocumentMutations
1405
- * index to iterate over all at document mutations for a given path or lower.
1406
- */
1407
- static prefixForPath(userId, path) {
1408
- return [userId, encodeResourcePath(path)];
1409
- }
1410
- /**
1411
- * Creates a full index key of [userId, encodedPath, batchId] for inserting
1412
- * and deleting into the DbDocumentMutations index.
1413
- */
1414
- static key(userId, path, batchId) {
1415
- return [userId, encodeResourcePath(path), batchId];
1416
- }
1273
+ function newDbDocumentMutationPrefixForUser(userId) {
1274
+ return [userId];
1417
1275
  }
1418
- DbDocumentMutation.store = 'documentMutations';
1419
- /**
1420
- * Because we store all the useful information for this store in the key,
1421
- * there is no useful information to store as the value. The raw (unencoded)
1422
- * path cannot be stored because IndexedDb doesn't store prototype
1423
- * information.
1424
- */
1425
- DbDocumentMutation.PLACEHOLDER = new DbDocumentMutation();
1426
1276
  /**
1427
- * Represents the known absence of a document at a particular version.
1428
- * Stored in IndexedDb as part of a DbRemoteDocument object.
1277
+ * Creates a [userId, encodedPath] key for use in the DbDocumentMutations
1278
+ * index to iterate over all at document mutations for a given path or lower.
1429
1279
  */
1430
- class DbNoDocument {
1431
- constructor(path, readTime) {
1432
- this.path = path;
1433
- this.readTime = readTime;
1434
- }
1280
+ function newDbDocumentMutationPrefixForPath(userId, path) {
1281
+ return [userId, encodeResourcePath(path)];
1435
1282
  }
1436
1283
  /**
1437
- * Represents a document that is known to exist but whose data is unknown.
1438
- * Stored in IndexedDb as part of a DbRemoteDocument object.
1284
+ * Creates a full index key of [userId, encodedPath, batchId] for inserting
1285
+ * and deleting into the DbDocumentMutations index.
1439
1286
  */
1440
- class DbUnknownDocument {
1441
- constructor(path, version) {
1442
- this.path = path;
1443
- this.version = version;
1444
- }
1287
+ function newDbDocumentMutationKey(userId, path, batchId) {
1288
+ return [userId, encodeResourcePath(path), batchId];
1445
1289
  }
1446
1290
  /**
1447
- * An object to be stored in the 'remoteDocuments' store in IndexedDb.
1448
- * It represents either:
1449
- *
1450
- * - A complete document.
1451
- * - A "no document" representing a document that is known not to exist (at
1452
- * some version).
1453
- * - An "unknown document" representing a document that is known to exist (at
1454
- * some version) but whose contents are unknown.
1455
- *
1456
- * Note: This is the persisted equivalent of a MaybeDocument and could perhaps
1457
- * be made more general if necessary.
1291
+ * Because we store all the useful information for this store in the key,
1292
+ * there is no useful information to store as the value. The raw (unencoded)
1293
+ * path cannot be stored because IndexedDb doesn't store prototype
1294
+ * information.
1458
1295
  */
1459
- class DbRemoteDocument {
1460
- // TODO: We are currently storing full document keys almost three times
1461
- // (once as part of the primary key, once - partly - as `parentPath` and once
1462
- // inside the encoded documents). During our next migration, we should
1463
- // rewrite the primary key as parentPath + document ID which would allow us
1464
- // to drop one value.
1465
- constructor(
1466
- /**
1467
- * Set to an instance of DbUnknownDocument if the data for a document is
1468
- * not known, but it is known that a document exists at the specified
1469
- * version (e.g. it had a successful update applied to it)
1470
- */
1471
- unknownDocument,
1472
- /**
1473
- * Set to an instance of a DbNoDocument if it is known that no document
1474
- * exists.
1475
- */
1476
- noDocument,
1477
- /**
1478
- * Set to an instance of a Document if there's a cached version of the
1479
- * document.
1480
- */
1481
- document,
1482
- /**
1483
- * Documents that were written to the remote document store based on
1484
- * a write acknowledgment are marked with `hasCommittedMutations`. These
1485
- * documents are potentially inconsistent with the backend's copy and use
1486
- * the write's commit version as their document version.
1487
- */
1488
- hasCommittedMutations,
1489
- /**
1490
- * When the document was read from the backend. Undefined for data written
1491
- * prior to schema version 9.
1492
- */
1493
- readTime,
1494
- /**
1495
- * The path of the collection this document is part of. Undefined for data
1496
- * written prior to schema version 9.
1497
- */
1498
- parentPath) {
1499
- this.unknownDocument = unknownDocument;
1500
- this.noDocument = noDocument;
1501
- this.document = document;
1502
- this.hasCommittedMutations = hasCommittedMutations;
1503
- this.readTime = readTime;
1504
- this.parentPath = parentPath;
1505
- }
1506
- }
1507
- DbRemoteDocument.store = 'remoteDocuments';
1296
+ const DbDocumentMutationPlaceholder = {};
1297
+ const DbDocumentMutationStore = 'documentMutations';
1298
+ const DbRemoteDocumentStore = 'remoteDocuments';
1508
1299
  /**
1509
1300
  * An index that provides access to all entries sorted by read time (which
1510
1301
  * corresponds to the last modification time of each row).
1511
1302
  *
1512
1303
  * This index is used to provide a changelog for Multi-Tab.
1513
1304
  */
1514
- DbRemoteDocument.readTimeIndex = 'readTimeIndex';
1515
- DbRemoteDocument.readTimeIndexPath = 'readTime';
1305
+ const DbRemoteDocumentReadTimeIndex = 'readTimeIndex';
1306
+ const DbRemoteDocumentReadTimeIndexPath = 'readTime';
1516
1307
  /**
1517
1308
  * An index that provides access to documents in a collection sorted by read
1518
1309
  * time.
@@ -1520,310 +1311,55 @@ DbRemoteDocument.readTimeIndexPath = 'readTime';
1520
1311
  * This index is used to allow the RemoteDocumentCache to fetch newly changed
1521
1312
  * documents in a collection.
1522
1313
  */
1523
- DbRemoteDocument.collectionReadTimeIndex = 'collectionReadTimeIndex';
1524
- DbRemoteDocument.collectionReadTimeIndexPath = ['parentPath', 'readTime'];
1525
- /**
1526
- * Contains a single entry that has metadata about the remote document cache.
1527
- */
1528
- class DbRemoteDocumentGlobal {
1529
- /**
1530
- * @param byteSize - Approximately the total size in bytes of all the
1531
- * documents in the document cache.
1532
- */
1533
- constructor(byteSize) {
1534
- this.byteSize = byteSize;
1535
- }
1536
- }
1537
- DbRemoteDocumentGlobal.store = 'remoteDocumentGlobal';
1538
- DbRemoteDocumentGlobal.key = 'remoteDocumentGlobalKey';
1539
- /**
1540
- * An object to be stored in the 'targets' store in IndexedDb.
1541
- *
1542
- * This is based on and should be kept in sync with the proto used in the iOS
1543
- * client.
1544
- *
1545
- * Each query the client listens to against the server is tracked on disk so
1546
- * that the query can be efficiently resumed on restart.
1547
- */
1548
- class DbTarget {
1549
- constructor(
1550
- /**
1551
- * An auto-generated sequential numeric identifier for the query.
1552
- *
1553
- * Queries are stored using their canonicalId as the key, but these
1554
- * canonicalIds can be quite long so we additionally assign a unique
1555
- * queryId which can be used by referenced data structures (e.g.
1556
- * indexes) to minimize the on-disk cost.
1557
- */
1558
- targetId,
1559
- /**
1560
- * The canonical string representing this query. This is not unique.
1561
- */
1562
- canonicalId,
1563
- /**
1564
- * The last readTime received from the Watch Service for this query.
1565
- *
1566
- * This is the same value as TargetChange.read_time in the protos.
1567
- */
1568
- readTime,
1569
- /**
1570
- * An opaque, server-assigned token that allows watching a query to be
1571
- * resumed after disconnecting without retransmitting all the data
1572
- * that matches the query. The resume token essentially identifies a
1573
- * point in time from which the server should resume sending results.
1574
- *
1575
- * This is related to the snapshotVersion in that the resumeToken
1576
- * effectively also encodes that value, but the resumeToken is opaque
1577
- * and sometimes encodes additional information.
1578
- *
1579
- * A consequence of this is that the resumeToken should be used when
1580
- * asking the server to reason about where this client is in the watch
1581
- * stream, but the client should use the snapshotVersion for its own
1582
- * purposes.
1583
- *
1584
- * This is the same value as TargetChange.resume_token in the protos.
1585
- */
1586
- resumeToken,
1587
- /**
1588
- * A sequence number representing the last time this query was
1589
- * listened to, used for garbage collection purposes.
1590
- *
1591
- * Conventionally this would be a timestamp value, but device-local
1592
- * clocks are unreliable and they must be able to create new listens
1593
- * even while disconnected. Instead this should be a monotonically
1594
- * increasing number that's incremented on each listen call.
1595
- *
1596
- * This is different from the queryId since the queryId is an
1597
- * immutable identifier assigned to the Query on first use while
1598
- * lastListenSequenceNumber is updated every time the query is
1599
- * listened to.
1600
- */
1601
- lastListenSequenceNumber,
1602
- /**
1603
- * Denotes the maximum snapshot version at which the associated query view
1604
- * contained no limbo documents. Undefined for data written prior to
1605
- * schema version 9.
1606
- */
1607
- lastLimboFreeSnapshotVersion,
1608
- /**
1609
- * The query for this target.
1610
- *
1611
- * Because canonical ids are not unique we must store the actual query. We
1612
- * use the proto to have an object we can persist without having to
1613
- * duplicate translation logic to and from a `Query` object.
1614
- */
1615
- query) {
1616
- this.targetId = targetId;
1617
- this.canonicalId = canonicalId;
1618
- this.readTime = readTime;
1619
- this.resumeToken = resumeToken;
1620
- this.lastListenSequenceNumber = lastListenSequenceNumber;
1621
- this.lastLimboFreeSnapshotVersion = lastLimboFreeSnapshotVersion;
1622
- this.query = query;
1623
- }
1624
- }
1625
- DbTarget.store = 'targets';
1314
+ const DbRemoteDocumentCollectionReadTimeIndex = 'collectionReadTimeIndex';
1315
+ const DbRemoteDocumentCollectionReadTimeIndexPath = [
1316
+ 'parentPath',
1317
+ 'readTime'
1318
+ ];
1319
+ const DbRemoteDocumentGlobalStore = 'remoteDocumentGlobal';
1320
+ const DbRemoteDocumentGlobalKey = 'remoteDocumentGlobalKey';
1321
+ const DbTargetStore = 'targets';
1626
1322
  /** Keys are automatically assigned via the targetId property. */
1627
- DbTarget.keyPath = 'targetId';
1323
+ const DbTargetKeyPath = 'targetId';
1628
1324
  /** The name of the queryTargets index. */
1629
- DbTarget.queryTargetsIndexName = 'queryTargetsIndex';
1325
+ const DbTargetQueryTargetsIndexName = 'queryTargetsIndex';
1630
1326
  /**
1631
1327
  * The index of all canonicalIds to the targets that they match. This is not
1632
1328
  * a unique mapping because canonicalId does not promise a unique name for all
1633
1329
  * possible queries, so we append the targetId to make the mapping unique.
1634
1330
  */
1635
- DbTarget.queryTargetsKeyPath = ['canonicalId', 'targetId'];
1636
- /**
1637
- * An object representing an association between a target and a document, or a
1638
- * sentinel row marking the last sequence number at which a document was used.
1639
- * Each document cached must have a corresponding sentinel row before lru
1640
- * garbage collection is enabled.
1641
- *
1642
- * The target associations and sentinel rows are co-located so that orphaned
1643
- * documents and their sequence numbers can be identified efficiently via a scan
1644
- * of this store.
1645
- */
1646
- class DbTargetDocument {
1647
- constructor(
1648
- /**
1649
- * The targetId identifying a target or 0 for a sentinel row.
1650
- */
1651
- targetId,
1652
- /**
1653
- * The path to the document, as encoded in the key.
1654
- */
1655
- path,
1656
- /**
1657
- * If this is a sentinel row, this should be the sequence number of the last
1658
- * time the document specified by `path` was used. Otherwise, it should be
1659
- * `undefined`.
1660
- */
1661
- sequenceNumber) {
1662
- this.targetId = targetId;
1663
- this.path = path;
1664
- this.sequenceNumber = sequenceNumber;
1665
- }
1666
- }
1331
+ const DbTargetQueryTargetsKeyPath = ['canonicalId', 'targetId'];
1667
1332
  /** Name of the IndexedDb object store. */
1668
- DbTargetDocument.store = 'targetDocuments';
1333
+ const DbTargetDocumentStore = 'targetDocuments';
1669
1334
  /** Keys are automatically assigned via the targetId, path properties. */
1670
- DbTargetDocument.keyPath = ['targetId', 'path'];
1335
+ const DbTargetDocumentKeyPath = ['targetId', 'path'];
1671
1336
  /** The index name for the reverse index. */
1672
- DbTargetDocument.documentTargetsIndex = 'documentTargetsIndex';
1337
+ const DbTargetDocumentDocumentTargetsIndex = 'documentTargetsIndex';
1673
1338
  /** We also need to create the reverse index for these properties. */
1674
- DbTargetDocument.documentTargetsKeyPath = ['path', 'targetId'];
1675
- /**
1676
- * A record of global state tracked across all Targets, tracked separately
1677
- * to avoid the need for extra indexes.
1678
- *
1679
- * This should be kept in-sync with the proto used in the iOS client.
1680
- */
1681
- class DbTargetGlobal {
1682
- constructor(
1683
- /**
1684
- * The highest numbered target id across all targets.
1685
- *
1686
- * See DbTarget.targetId.
1687
- */
1688
- highestTargetId,
1689
- /**
1690
- * The highest numbered lastListenSequenceNumber across all targets.
1691
- *
1692
- * See DbTarget.lastListenSequenceNumber.
1693
- */
1694
- highestListenSequenceNumber,
1695
- /**
1696
- * A global snapshot version representing the last consistent snapshot we
1697
- * received from the backend. This is monotonically increasing and any
1698
- * snapshots received from the backend prior to this version (e.g. for
1699
- * targets resumed with a resumeToken) should be suppressed (buffered)
1700
- * until the backend has caught up to this snapshot version again. This
1701
- * prevents our cache from ever going backwards in time.
1702
- */
1703
- lastRemoteSnapshotVersion,
1704
- /**
1705
- * The number of targets persisted.
1706
- */
1707
- targetCount) {
1708
- this.highestTargetId = highestTargetId;
1709
- this.highestListenSequenceNumber = highestListenSequenceNumber;
1710
- this.lastRemoteSnapshotVersion = lastRemoteSnapshotVersion;
1711
- this.targetCount = targetCount;
1712
- }
1713
- }
1339
+ const DbTargetDocumentDocumentTargetsKeyPath = ['path', 'targetId'];
1714
1340
  /**
1715
1341
  * The key string used for the single object that exists in the
1716
1342
  * DbTargetGlobal store.
1717
1343
  */
1718
- DbTargetGlobal.key = 'targetGlobalKey';
1719
- DbTargetGlobal.store = 'targetGlobal';
1720
- /**
1721
- * An object representing an association between a Collection id (e.g. 'messages')
1722
- * to a parent path (e.g. '/chats/123') that contains it as a (sub)collection.
1723
- * This is used to efficiently find all collections to query when performing
1724
- * a Collection Group query.
1725
- */
1726
- class DbCollectionParent {
1727
- constructor(
1728
- /**
1729
- * The collectionId (e.g. 'messages')
1730
- */
1731
- collectionId,
1732
- /**
1733
- * The path to the parent (either a document location or an empty path for
1734
- * a root-level collection).
1735
- */
1736
- parent) {
1737
- this.collectionId = collectionId;
1738
- this.parent = parent;
1739
- }
1740
- }
1344
+ const DbTargetGlobalKey = 'targetGlobalKey';
1345
+ const DbTargetGlobalStore = 'targetGlobal';
1741
1346
  /** Name of the IndexedDb object store. */
1742
- DbCollectionParent.store = 'collectionParents';
1347
+ const DbCollectionParentStore = 'collectionParents';
1743
1348
  /** Keys are automatically assigned via the collectionId, parent properties. */
1744
- DbCollectionParent.keyPath = ['collectionId', 'parent'];
1745
- /**
1746
- * A record of the metadata state of each client.
1747
- *
1748
- * PORTING NOTE: This is used to synchronize multi-tab state and does not need
1749
- * to be ported to iOS or Android.
1750
- */
1751
- class DbClientMetadata {
1752
- constructor(
1753
- // Note: Previous schema versions included a field
1754
- // "lastProcessedDocumentChangeId". Don't use anymore.
1755
- /** The auto-generated client id assigned at client startup. */
1756
- clientId,
1757
- /** The last time this state was updated. */
1758
- updateTimeMs,
1759
- /** Whether the client's network connection is enabled. */
1760
- networkEnabled,
1761
- /** Whether this client is running in a foreground tab. */
1762
- inForeground) {
1763
- this.clientId = clientId;
1764
- this.updateTimeMs = updateTimeMs;
1765
- this.networkEnabled = networkEnabled;
1766
- this.inForeground = inForeground;
1767
- }
1768
- }
1349
+ const DbCollectionParentKeyPath = ['collectionId', 'parent'];
1769
1350
  /** Name of the IndexedDb object store. */
1770
- DbClientMetadata.store = 'clientMetadata';
1351
+ const DbClientMetadataStore = 'clientMetadata';
1771
1352
  /** Keys are automatically assigned via the clientId properties. */
1772
- DbClientMetadata.keyPath = 'clientId';
1773
- /** An object representing a bundle loaded by the SDK. */
1774
- class DbBundle {
1775
- constructor(
1776
- /** The ID of the loaded bundle. */
1777
- bundleId,
1778
- /** The create time of the loaded bundle. */
1779
- createTime,
1780
- /** The schema version of the loaded bundle. */
1781
- version) {
1782
- this.bundleId = bundleId;
1783
- this.createTime = createTime;
1784
- this.version = version;
1785
- }
1786
- }
1353
+ const DbClientMetadataKeyPath = 'clientId';
1787
1354
  /** Name of the IndexedDb object store. */
1788
- DbBundle.store = 'bundles';
1789
- DbBundle.keyPath = 'bundleId';
1790
- /** An object representing a named query loaded by the SDK via a bundle. */
1791
- class DbNamedQuery {
1792
- constructor(
1793
- /** The name of the query. */
1794
- name,
1795
- /** The read time of the results saved in the bundle from the named query. */
1796
- readTime,
1797
- /** The query saved in the bundle. */
1798
- bundledQuery) {
1799
- this.name = name;
1800
- this.readTime = readTime;
1801
- this.bundledQuery = bundledQuery;
1802
- }
1803
- }
1355
+ const DbBundleStore = 'bundles';
1356
+ const DbBundleKeyPath = 'bundleId';
1804
1357
  /** Name of the IndexedDb object store. */
1805
- DbNamedQuery.store = 'namedQueries';
1806
- DbNamedQuery.keyPath = 'name';
1807
- /** An object representing the global configuration for a field index. */
1808
- class DbIndexConfiguration {
1809
- constructor(
1810
- /**
1811
- * The index id for this entry. Undefined for indexes that are not yet
1812
- * persisted.
1813
- */
1814
- indexId,
1815
- /** The collection group this index belongs to. */
1816
- collectionGroup,
1817
- /** The fields to index for this index. */
1818
- fields) {
1819
- this.indexId = indexId;
1820
- this.collectionGroup = collectionGroup;
1821
- this.fields = fields;
1822
- }
1823
- }
1358
+ const DbNamedQueryStore = 'namedQueries';
1359
+ const DbNamedQueryKeyPath = 'name';
1824
1360
  /** Name of the IndexedDb object store. */
1825
- DbIndexConfiguration.store = 'indexConfiguration';
1826
- DbIndexConfiguration.keyPath = 'indexId';
1361
+ const DbIndexConfigurationStore = 'indexConfiguration';
1362
+ const DbIndexConfigurationKeyPath = 'indexId';
1827
1363
  /**
1828
1364
  * An index that provides access to the index configurations by collection
1829
1365
  * group.
@@ -1832,49 +1368,11 @@ DbIndexConfiguration.keyPath = 'indexId';
1832
1368
  * not possible here as the Web client supports concurrent access to
1833
1369
  * persistence via multi-tab.
1834
1370
  */
1835
- DbIndexConfiguration.collectionGroupIndex = 'collectionGroupIndex';
1836
- DbIndexConfiguration.collectionGroupIndexPath = 'collectionGroup';
1837
- /**
1838
- * An object describing how up-to-date the index backfill is for each user and
1839
- * index.
1840
- */
1841
- class DbIndexState {
1842
- constructor(
1843
- /** The index id for this entry. */
1844
- indexId,
1845
- /** The user id for this entry. */
1846
- uid,
1847
- /**
1848
- * A number that indicates when the index was last updated (relative to
1849
- * other indexes).
1850
- */
1851
- sequenceNumber,
1852
- /**
1853
- * The latest read time that has been indexed by Firestore for this field
1854
- * index. Set to `{seconds: 0, nanos: 0}` if no documents have been indexed.
1855
- */
1856
- readTime,
1857
- /**
1858
- * The last document that has been indexed for this field index. Empty if
1859
- * no documents have been indexed.
1860
- */
1861
- documentKey,
1862
- /**
1863
- * The largest mutation batch id that has been processed for this index. -1
1864
- * if no mutations have been indexed.
1865
- */
1866
- largestBatchId) {
1867
- this.indexId = indexId;
1868
- this.uid = uid;
1869
- this.sequenceNumber = sequenceNumber;
1870
- this.readTime = readTime;
1871
- this.documentKey = documentKey;
1872
- this.largestBatchId = largestBatchId;
1873
- }
1874
- }
1371
+ const DbIndexConfigurationCollectionGroupIndex = 'collectionGroupIndex';
1372
+ const DbIndexConfigurationCollectionGroupIndexPath = 'collectionGroup';
1875
1373
  /** Name of the IndexedDb object store. */
1876
- DbIndexState.store = 'indexState';
1877
- DbIndexState.keyPath = ['indexId', 'uid'];
1374
+ const DbIndexStateStore = 'indexState';
1375
+ const DbIndexStateKeyPath = ['indexId', 'uid'];
1878
1376
  /**
1879
1377
  * An index that provides access to documents in a collection sorted by last
1880
1378
  * update time. Used by the backfiller.
@@ -1883,108 +1381,66 @@ DbIndexState.keyPath = ['indexId', 'uid'];
1883
1381
  * not possible here as the Web client supports concurrent access to
1884
1382
  * persistence via multi-tab.
1885
1383
  */
1886
- DbIndexState.sequenceNumberIndex = 'sequenceNumberIndex';
1887
- DbIndexState.sequenceNumberIndexPath = ['uid', 'sequenceNumber'];
1888
- /** An object that stores the encoded entries for all documents and fields. */
1889
- class DbIndexEntry {
1890
- constructor(
1891
- /** The index id for this entry. */
1892
- indexId,
1893
- /** The user id for this entry. */
1894
- uid,
1895
- /** The encoded array index value for this entry. */
1896
- arrayValue,
1897
- /** The encoded directional value for equality and inequality filters. */
1898
- directionalValue,
1899
- /** The document key this entry points to. */
1900
- documentKey) {
1901
- this.indexId = indexId;
1902
- this.uid = uid;
1903
- this.arrayValue = arrayValue;
1904
- this.directionalValue = directionalValue;
1905
- this.documentKey = documentKey;
1906
- }
1907
- }
1384
+ const DbIndexStateSequenceNumberIndex = 'sequenceNumberIndex';
1385
+ const DbIndexStateSequenceNumberIndexPath = ['uid', 'sequenceNumber'];
1908
1386
  /** Name of the IndexedDb object store. */
1909
- DbIndexEntry.store = 'indexEntries';
1910
- DbIndexEntry.keyPath = [
1387
+ const DbIndexEntryStore = 'indexEntries';
1388
+ const DbIndexEntryKeyPath = [
1911
1389
  'indexId',
1912
1390
  'uid',
1913
1391
  'arrayValue',
1914
1392
  'directionalValue',
1915
- 'documentKey'
1916
- ];
1917
- DbIndexEntry.documentKeyIndex = 'documentKeyIndex';
1918
- DbIndexEntry.documentKeyIndexPath = ['indexId', 'uid', 'documentKey'];
1919
- /**
1920
- * An object representing a document overlay.
1921
- */
1922
- class DbDocumentOverlay {
1923
- constructor(
1924
- /** The user ID to whom this overlay belongs. */
1925
- userId,
1926
- /** The path to the collection that contains the document. */
1927
- collectionPath,
1928
- /** The ID (key) of the document within the collection. */
1929
- documentId,
1930
- /** The collection group to which the document belongs. */
1931
- collectionGroup,
1932
- /** The largest batch ID that's been applied for this overlay. */
1933
- largestBatchId,
1934
- /** The overlay mutation. */
1935
- overlayMutation) {
1936
- this.userId = userId;
1937
- this.collectionPath = collectionPath;
1938
- this.documentId = documentId;
1939
- this.collectionGroup = collectionGroup;
1940
- this.largestBatchId = largestBatchId;
1941
- this.overlayMutation = overlayMutation;
1942
- }
1943
- }
1393
+ 'documentKey'
1394
+ ];
1395
+ const DbIndexEntryDocumentKeyIndex = 'documentKeyIndex';
1396
+ const DbIndexEntryDocumentKeyIndexPath = [
1397
+ 'indexId',
1398
+ 'uid',
1399
+ 'documentKey'
1400
+ ];
1944
1401
  /** Name of the IndexedDb object store. */
1945
- DbDocumentOverlay.store = 'documentOverlays';
1946
- DbDocumentOverlay.keyPath = ['userId', 'collectionPath', 'documentId'];
1947
- DbDocumentOverlay.collectionPathOverlayIndex = 'collectionPathOverlayIndex';
1948
- DbDocumentOverlay.collectionPathOverlayIndexPath = [
1402
+ const DbDocumentOverlayStore = 'documentOverlays';
1403
+ const DbDocumentOverlayKeyPath = [
1404
+ 'userId',
1405
+ 'collectionPath',
1406
+ 'documentId'
1407
+ ];
1408
+ const DbDocumentOverlayCollectionPathOverlayIndex = 'collectionPathOverlayIndex';
1409
+ const DbDocumentOverlayCollectionPathOverlayIndexPath = [
1949
1410
  'userId',
1950
1411
  'collectionPath',
1951
1412
  'largestBatchId'
1952
1413
  ];
1953
- DbDocumentOverlay.collectionGroupOverlayIndex = 'collectionGroupOverlayIndex';
1954
- DbDocumentOverlay.collectionGroupOverlayIndexPath = [
1414
+ const DbDocumentOverlayCollectionGroupOverlayIndex = 'collectionGroupOverlayIndex';
1415
+ const DbDocumentOverlayCollectionGroupOverlayIndexPath = [
1955
1416
  'userId',
1956
1417
  'collectionGroup',
1957
1418
  'largestBatchId'
1958
1419
  ];
1959
1420
  // Visible for testing
1960
1421
  const V1_STORES = [
1961
- DbMutationQueue.store,
1962
- DbMutationBatch.store,
1963
- DbDocumentMutation.store,
1964
- DbRemoteDocument.store,
1965
- DbTarget.store,
1966
- DbPrimaryClient.store,
1967
- DbTargetGlobal.store,
1968
- DbTargetDocument.store
1422
+ DbMutationQueueStore,
1423
+ DbMutationBatchStore,
1424
+ DbDocumentMutationStore,
1425
+ DbRemoteDocumentStore,
1426
+ DbTargetStore,
1427
+ DbPrimaryClientStore,
1428
+ DbTargetGlobalStore,
1429
+ DbTargetDocumentStore
1969
1430
  ];
1970
- // V2 is no longer usable (see comment at top of file)
1971
1431
  // Visible for testing
1972
1432
  const V3_STORES = V1_STORES;
1973
1433
  // Note: DbRemoteDocumentChanges is no longer used and dropped with v9.
1974
- const V4_STORES = [...V3_STORES, DbClientMetadata.store];
1975
- // V5 does not change the set of stores.
1976
- const V6_STORES = [...V4_STORES, DbRemoteDocumentGlobal.store];
1977
- // V7 does not change the set of stores.
1978
- const V8_STORES = [...V6_STORES, DbCollectionParent.store];
1979
- // V9 does not change the set of stores.
1980
- // V10 does not change the set of stores.
1981
- const V11_STORES = [...V8_STORES, DbBundle.store, DbNamedQuery.store];
1982
- const V12_STORES = [...V11_STORES, DbDocumentOverlay.store];
1434
+ const V4_STORES = [...V3_STORES, DbClientMetadataStore];
1435
+ const V6_STORES = [...V4_STORES, DbRemoteDocumentGlobalStore];
1436
+ const V8_STORES = [...V6_STORES, DbCollectionParentStore];
1437
+ const V11_STORES = [...V8_STORES, DbBundleStore, DbNamedQueryStore];
1438
+ const V12_STORES = [...V11_STORES, DbDocumentOverlayStore];
1983
1439
  const V13_STORES = [
1984
1440
  ...V12_STORES,
1985
- DbIndexConfiguration.store,
1986
- DbIndexState.store,
1987
- DbIndexEntry.store
1441
+ DbIndexConfigurationStore,
1442
+ DbIndexStateStore,
1443
+ DbIndexEntryStore
1988
1444
  ];
1989
1445
  /** Returns the object stores for the provided schema. */
1990
1446
  function getObjectStores(schemaVersion) {
@@ -5701,6 +5157,116 @@ function compareDocs(orderBy, d1, d2) {
5701
5157
  }
5702
5158
  }
5703
5159
 
5160
+ /**
5161
+ * @license
5162
+ * Copyright 2017 Google LLC
5163
+ *
5164
+ * Licensed under the Apache License, Version 2.0 (the "License");
5165
+ * you may not use this file except in compliance with the License.
5166
+ * You may obtain a copy of the License at
5167
+ *
5168
+ * http://www.apache.org/licenses/LICENSE-2.0
5169
+ *
5170
+ * Unless required by applicable law or agreed to in writing, software
5171
+ * distributed under the License is distributed on an "AS IS" BASIS,
5172
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5173
+ * See the License for the specific language governing permissions and
5174
+ * limitations under the License.
5175
+ */
5176
+ /**
5177
+ * A map implementation that uses objects as keys. Objects must have an
5178
+ * associated equals function and must be immutable. Entries in the map are
5179
+ * stored together with the key being produced from the mapKeyFn. This map
5180
+ * automatically handles collisions of keys.
5181
+ */
5182
+ class ObjectMap {
5183
+ constructor(mapKeyFn, equalsFn) {
5184
+ this.mapKeyFn = mapKeyFn;
5185
+ this.equalsFn = equalsFn;
5186
+ /**
5187
+ * The inner map for a key/value pair. Due to the possibility of collisions we
5188
+ * keep a list of entries that we do a linear search through to find an actual
5189
+ * match. Note that collisions should be rare, so we still expect near
5190
+ * constant time lookups in practice.
5191
+ */
5192
+ this.inner = {};
5193
+ /** The number of entries stored in the map */
5194
+ this.innerSize = 0;
5195
+ }
5196
+ /** Get a value for this key, or undefined if it does not exist. */
5197
+ get(key) {
5198
+ const id = this.mapKeyFn(key);
5199
+ const matches = this.inner[id];
5200
+ if (matches === undefined) {
5201
+ return undefined;
5202
+ }
5203
+ for (const [otherKey, value] of matches) {
5204
+ if (this.equalsFn(otherKey, key)) {
5205
+ return value;
5206
+ }
5207
+ }
5208
+ return undefined;
5209
+ }
5210
+ has(key) {
5211
+ return this.get(key) !== undefined;
5212
+ }
5213
+ /** Put this key and value in the map. */
5214
+ set(key, value) {
5215
+ const id = this.mapKeyFn(key);
5216
+ const matches = this.inner[id];
5217
+ if (matches === undefined) {
5218
+ this.inner[id] = [[key, value]];
5219
+ this.innerSize++;
5220
+ return;
5221
+ }
5222
+ for (let i = 0; i < matches.length; i++) {
5223
+ if (this.equalsFn(matches[i][0], key)) {
5224
+ // This is updating an existing entry and does not increase `innerSize`.
5225
+ matches[i] = [key, value];
5226
+ return;
5227
+ }
5228
+ }
5229
+ matches.push([key, value]);
5230
+ this.innerSize++;
5231
+ }
5232
+ /**
5233
+ * Remove this key from the map. Returns a boolean if anything was deleted.
5234
+ */
5235
+ delete(key) {
5236
+ const id = this.mapKeyFn(key);
5237
+ const matches = this.inner[id];
5238
+ if (matches === undefined) {
5239
+ return false;
5240
+ }
5241
+ for (let i = 0; i < matches.length; i++) {
5242
+ if (this.equalsFn(matches[i][0], key)) {
5243
+ if (matches.length === 1) {
5244
+ delete this.inner[id];
5245
+ }
5246
+ else {
5247
+ matches.splice(i, 1);
5248
+ }
5249
+ this.innerSize--;
5250
+ return true;
5251
+ }
5252
+ }
5253
+ return false;
5254
+ }
5255
+ forEach(fn) {
5256
+ forEach(this.inner, (_, entries) => {
5257
+ for (const [k, v] of entries) {
5258
+ fn(k, v);
5259
+ }
5260
+ });
5261
+ }
5262
+ isEmpty() {
5263
+ return isEmpty(this.inner);
5264
+ }
5265
+ size() {
5266
+ return this.innerSize;
5267
+ }
5268
+ }
5269
+
5704
5270
  /**
5705
5271
  * @license
5706
5272
  * Copyright 2017 Google LLC
@@ -6412,6 +5978,9 @@ const EMPTY_DOCUMENT_MAP = new SortedMap(DocumentKey.comparator);
6412
5978
  function documentMap() {
6413
5979
  return EMPTY_DOCUMENT_MAP;
6414
5980
  }
5981
+ function newOverlayMap() {
5982
+ return new ObjectMap(key => key.toString(), (l, r) => l.isEqual(r));
5983
+ }
6415
5984
  const EMPTY_DOCUMENT_VERSION_MAP = new SortedMap(DocumentKey.comparator);
6416
5985
  function documentVersionMap() {
6417
5986
  return EMPTY_DOCUMENT_VERSION_MAP;
@@ -9090,30 +8659,36 @@ function fromDbRemoteDocument(localSerializer, remoteDoc) {
9090
8659
  }
9091
8660
  /** Encodes a document for storage locally. */
9092
8661
  function toDbRemoteDocument(localSerializer, document) {
9093
- const dbReadTime = toDbTimestampKey(document.readTime);
9094
8662
  const parentPath = document.key.path.popLast().toArray();
8663
+ const readTime = toDbTimestampKey(document.readTime);
9095
8664
  if (document.isFoundDocument()) {
9096
8665
  const doc = toDocument(localSerializer.remoteSerializer, document);
9097
8666
  const hasCommittedMutations = document.hasCommittedMutations;
9098
- return new DbRemoteDocument(
9099
- /* unknownDocument= */ null,
9100
- /* noDocument= */ null, doc, hasCommittedMutations, dbReadTime, parentPath);
8667
+ return {
8668
+ document: doc,
8669
+ hasCommittedMutations,
8670
+ readTime,
8671
+ parentPath
8672
+ };
9101
8673
  }
9102
8674
  else if (document.isNoDocument()) {
9103
8675
  const path = document.key.path.toArray();
9104
- const version = toDbTimestamp(document.version);
9105
8676
  const hasCommittedMutations = document.hasCommittedMutations;
9106
- return new DbRemoteDocument(
9107
- /* unknownDocument= */ null, new DbNoDocument(path, version),
9108
- /* document= */ null, hasCommittedMutations, dbReadTime, parentPath);
8677
+ return {
8678
+ noDocument: { path, readTime: toDbTimestamp(document.version) },
8679
+ hasCommittedMutations,
8680
+ readTime,
8681
+ parentPath
8682
+ };
9109
8683
  }
9110
8684
  else if (document.isUnknownDocument()) {
9111
8685
  const path = document.key.path.toArray();
9112
- const readTime = toDbTimestamp(document.version);
9113
- return new DbRemoteDocument(new DbUnknownDocument(path, readTime),
9114
- /* noDocument= */ null,
9115
- /* document= */ null,
9116
- /* hasCommittedMutations= */ true, dbReadTime, parentPath);
8686
+ return {
8687
+ unknownDocument: { path, version: toDbTimestamp(document.version) },
8688
+ hasCommittedMutations: true,
8689
+ readTime,
8690
+ parentPath
8691
+ };
9117
8692
  }
9118
8693
  else {
9119
8694
  return fail();
@@ -9129,7 +8704,7 @@ function fromDbTimestampKey(dbTimestampKey) {
9129
8704
  }
9130
8705
  function toDbTimestamp(snapshotVersion) {
9131
8706
  const timestamp = snapshotVersion.toTimestamp();
9132
- return new DbTimestamp(timestamp.seconds, timestamp.nanoseconds);
8707
+ return { seconds: timestamp.seconds, nanoseconds: timestamp.nanoseconds };
9133
8708
  }
9134
8709
  function fromDbTimestamp(dbTimestamp) {
9135
8710
  const timestamp = new Timestamp(dbTimestamp.seconds, dbTimestamp.nanoseconds);
@@ -9139,7 +8714,13 @@ function fromDbTimestamp(dbTimestamp) {
9139
8714
  function toDbMutationBatch(localSerializer, userId, batch) {
9140
8715
  const serializedBaseMutations = batch.baseMutations.map(m => toMutation(localSerializer.remoteSerializer, m));
9141
8716
  const serializedMutations = batch.mutations.map(m => toMutation(localSerializer.remoteSerializer, m));
9142
- return new DbMutationBatch(userId, batch.batchId, batch.localWriteTime.toMillis(), serializedBaseMutations, serializedMutations);
8717
+ return {
8718
+ userId,
8719
+ batchId: batch.batchId,
8720
+ localWriteTimeMs: batch.localWriteTime.toMillis(),
8721
+ baseMutations: serializedBaseMutations,
8722
+ mutations: serializedMutations
8723
+ };
9143
8724
  }
9144
8725
  /** Decodes a DbMutationBatch into a MutationBatch */
9145
8726
  function fromDbMutationBatch(localSerializer, dbBatch) {
@@ -9195,7 +8776,15 @@ function toDbTarget(localSerializer, targetData) {
9195
8776
  // convert it to a base64 string for storage.
9196
8777
  const resumeToken = targetData.resumeToken.toBase64();
9197
8778
  // lastListenSequenceNumber is always 0 until we do real GC.
9198
- return new DbTarget(targetData.targetId, canonifyTarget(targetData.target), dbTimestamp, resumeToken, targetData.sequenceNumber, dbLastLimboFreeTimestamp, queryProto);
8779
+ return {
8780
+ targetId: targetData.targetId,
8781
+ canonicalId: canonifyTarget(targetData.target),
8782
+ readTime: dbTimestamp,
8783
+ resumeToken,
8784
+ lastListenSequenceNumber: targetData.sequenceNumber,
8785
+ lastLimboFreeSnapshotVersion: dbLastLimboFreeTimestamp,
8786
+ query: queryProto
8787
+ };
9199
8788
  }
9200
8789
  /**
9201
8790
  * A helper function for figuring out what kind of query has been stored.
@@ -9274,7 +8863,14 @@ function fromDbDocumentOverlay(localSerializer, dbDocumentOverlay) {
9274
8863
  /** Decodes an Overlay model object into a DbDocumentOverlay object. */
9275
8864
  function toDbDocumentOverlay(localSerializer, userId, overlay) {
9276
8865
  const [_, collectionPath, documentId] = toDbDocumentOverlayKey(userId, overlay.mutation.key);
9277
- return new DbDocumentOverlay(userId, collectionPath, documentId, overlay.mutation.key.getCollectionGroup(), overlay.largestBatchId, toMutation(localSerializer.remoteSerializer, overlay.mutation));
8866
+ return {
8867
+ userId,
8868
+ collectionPath,
8869
+ documentId,
8870
+ collectionGroup: overlay.mutation.key.getCollectionGroup(),
8871
+ largestBatchId: overlay.largestBatchId,
8872
+ overlayMutation: toMutation(localSerializer.remoteSerializer, overlay.mutation)
8873
+ };
9278
8874
  }
9279
8875
  /**
9280
8876
  * Returns the DbDocumentOverlayKey corresponding to the given user and
@@ -9286,7 +8882,11 @@ function toDbDocumentOverlayKey(userId, docKey) {
9286
8882
  return [userId, collectionPath, docId];
9287
8883
  }
9288
8884
  function toDbIndexConfiguration(index) {
9289
- return new DbIndexConfiguration(index.indexId, index.collectionGroup, index.fields.map(s => [s.fieldPath.canonicalString(), s.kind]));
8885
+ return {
8886
+ indexId: index.indexId,
8887
+ collectionGroup: index.collectionGroup,
8888
+ fields: index.fields.map(s => [s.fieldPath.canonicalString(), s.kind])
8889
+ };
9290
8890
  }
9291
8891
  function fromDbIndexConfiguration(index, state) {
9292
8892
  const decodedState = state
@@ -9296,7 +8896,14 @@ function fromDbIndexConfiguration(index, state) {
9296
8896
  return new FieldIndex(index.indexId, index.collectionGroup, decodedSegments, decodedState);
9297
8897
  }
9298
8898
  function toDbIndexState(indexId, user, sequenceNumber, offset) {
9299
- return new DbIndexState(indexId, user.uid || '', sequenceNumber, toDbTimestamp(offset.readTime), encodeResourcePath(offset.documentKey.path), offset.largestBatchId);
8899
+ return {
8900
+ indexId,
8901
+ uid: user.uid || '',
8902
+ sequenceNumber,
8903
+ readTime: toDbTimestamp(offset.readTime),
8904
+ documentKey: encodeResourcePath(offset.documentKey.path),
8905
+ largestBatchId: offset.largestBatchId
8906
+ };
9300
8907
  }
9301
8908
 
9302
8909
  /**
@@ -9347,13 +8954,13 @@ class IndexedDbBundleCache {
9347
8954
  * Helper to get a typed SimpleDbStore for the bundles object store.
9348
8955
  */
9349
8956
  function bundlesStore(txn) {
9350
- return getStore(txn, DbBundle.store);
8957
+ return getStore(txn, DbBundleStore);
9351
8958
  }
9352
8959
  /**
9353
8960
  * Helper to get a typed SimpleDbStore for the namedQueries object store.
9354
8961
  */
9355
8962
  function namedQueriesStore(txn) {
9356
- return getStore(txn, DbNamedQuery.store);
8963
+ return getStore(txn, DbNamedQueryStore);
9357
8964
  }
9358
8965
 
9359
8966
  /**
@@ -9400,7 +9007,7 @@ class IndexedDbDocumentOverlayCache {
9400
9007
  }
9401
9008
  saveOverlays(transaction, largestBatchId, overlays) {
9402
9009
  const promises = [];
9403
- overlays.forEach(mutation => {
9010
+ overlays.forEach((_, mutation) => {
9404
9011
  const overlay = new Overlay(largestBatchId, mutation);
9405
9012
  promises.push(this.saveOverlay(transaction, overlay));
9406
9013
  });
@@ -9415,19 +9022,19 @@ class IndexedDbDocumentOverlayCache {
9415
9022
  const range = IDBKeyRange.bound([this.userId, collectionPath, batchId], [this.userId, collectionPath, batchId + 1],
9416
9023
  /*lowerOpen=*/ false,
9417
9024
  /*upperOpen=*/ true);
9418
- promises.push(documentOverlayStore(transaction).deleteAll(DbDocumentOverlay.collectionPathOverlayIndex, range));
9025
+ promises.push(documentOverlayStore(transaction).deleteAll(DbDocumentOverlayCollectionPathOverlayIndex, range));
9419
9026
  });
9420
9027
  return PersistencePromise.waitFor(promises);
9421
9028
  }
9422
9029
  getOverlaysForCollection(transaction, collection, sinceBatchId) {
9423
- const result = new Map();
9030
+ const result = newOverlayMap();
9424
9031
  const collectionPath = encodeResourcePath(collection);
9425
9032
  // We want batch IDs larger than `sinceBatchId`, and so the lower bound
9426
9033
  // is not inclusive.
9427
9034
  const range = IDBKeyRange.bound([this.userId, collectionPath, sinceBatchId], [this.userId, collectionPath, Number.POSITIVE_INFINITY],
9428
9035
  /*lowerOpen=*/ true);
9429
9036
  return documentOverlayStore(transaction)
9430
- .loadAll(DbDocumentOverlay.collectionPathOverlayIndex, range)
9037
+ .loadAll(DbDocumentOverlayCollectionPathOverlayIndex, range)
9431
9038
  .next(dbOverlays => {
9432
9039
  for (const dbOverlay of dbOverlays) {
9433
9040
  const overlay = fromDbDocumentOverlay(this.serializer, dbOverlay);
@@ -9437,7 +9044,7 @@ class IndexedDbDocumentOverlayCache {
9437
9044
  });
9438
9045
  }
9439
9046
  getOverlaysForCollectionGroup(transaction, collectionGroup, sinceBatchId, count) {
9440
- const result = new Map();
9047
+ const result = newOverlayMap();
9441
9048
  let currentBatchId = undefined;
9442
9049
  // We want batch IDs larger than `sinceBatchId`, and so the lower bound
9443
9050
  // is not inclusive.
@@ -9445,7 +9052,7 @@ class IndexedDbDocumentOverlayCache {
9445
9052
  /*lowerOpen=*/ true);
9446
9053
  return documentOverlayStore(transaction)
9447
9054
  .iterate({
9448
- index: DbDocumentOverlay.collectionGroupOverlayIndex,
9055
+ index: DbDocumentOverlayCollectionGroupOverlayIndex,
9449
9056
  range
9450
9057
  }, (_, dbOverlay, control) => {
9451
9058
  // We do not want to return partial batch overlays, even if the size
@@ -9453,7 +9060,7 @@ class IndexedDbDocumentOverlayCache {
9453
9060
  // continue to aggregate results even after the result size exceeds
9454
9061
  // `count` if there are more overlays from the `currentBatchId`.
9455
9062
  const overlay = fromDbDocumentOverlay(this.serializer, dbOverlay);
9456
- if (result.size < count ||
9063
+ if (result.size() < count ||
9457
9064
  overlay.largestBatchId === currentBatchId) {
9458
9065
  result.set(overlay.getKey(), overlay);
9459
9066
  currentBatchId = overlay.largestBatchId;
@@ -9472,7 +9079,7 @@ class IndexedDbDocumentOverlayCache {
9472
9079
  * Helper to get a typed SimpleDbStore for the document overlay object store.
9473
9080
  */
9474
9081
  function documentOverlayStore(txn) {
9475
- return getStore(txn, DbDocumentOverlay.store);
9082
+ return getStore(txn, DbDocumentOverlayStore);
9476
9083
  }
9477
9084
 
9478
9085
  /**
@@ -10227,107 +9834,6 @@ class TargetIndexMatcher {
10227
9834
  }
10228
9835
  }
10229
9836
 
10230
- /**
10231
- * @license
10232
- * Copyright 2017 Google LLC
10233
- *
10234
- * Licensed under the Apache License, Version 2.0 (the "License");
10235
- * you may not use this file except in compliance with the License.
10236
- * You may obtain a copy of the License at
10237
- *
10238
- * http://www.apache.org/licenses/LICENSE-2.0
10239
- *
10240
- * Unless required by applicable law or agreed to in writing, software
10241
- * distributed under the License is distributed on an "AS IS" BASIS,
10242
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10243
- * See the License for the specific language governing permissions and
10244
- * limitations under the License.
10245
- */
10246
- /**
10247
- * A map implementation that uses objects as keys. Objects must have an
10248
- * associated equals function and must be immutable. Entries in the map are
10249
- * stored together with the key being produced from the mapKeyFn. This map
10250
- * automatically handles collisions of keys.
10251
- */
10252
- class ObjectMap {
10253
- constructor(mapKeyFn, equalsFn) {
10254
- this.mapKeyFn = mapKeyFn;
10255
- this.equalsFn = equalsFn;
10256
- /**
10257
- * The inner map for a key/value pair. Due to the possibility of collisions we
10258
- * keep a list of entries that we do a linear search through to find an actual
10259
- * match. Note that collisions should be rare, so we still expect near
10260
- * constant time lookups in practice.
10261
- */
10262
- this.inner = {};
10263
- }
10264
- /** Get a value for this key, or undefined if it does not exist. */
10265
- get(key) {
10266
- const id = this.mapKeyFn(key);
10267
- const matches = this.inner[id];
10268
- if (matches === undefined) {
10269
- return undefined;
10270
- }
10271
- for (const [otherKey, value] of matches) {
10272
- if (this.equalsFn(otherKey, key)) {
10273
- return value;
10274
- }
10275
- }
10276
- return undefined;
10277
- }
10278
- has(key) {
10279
- return this.get(key) !== undefined;
10280
- }
10281
- /** Put this key and value in the map. */
10282
- set(key, value) {
10283
- const id = this.mapKeyFn(key);
10284
- const matches = this.inner[id];
10285
- if (matches === undefined) {
10286
- this.inner[id] = [[key, value]];
10287
- return;
10288
- }
10289
- for (let i = 0; i < matches.length; i++) {
10290
- if (this.equalsFn(matches[i][0], key)) {
10291
- matches[i] = [key, value];
10292
- return;
10293
- }
10294
- }
10295
- matches.push([key, value]);
10296
- }
10297
- /**
10298
- * Remove this key from the map. Returns a boolean if anything was deleted.
10299
- */
10300
- delete(key) {
10301
- const id = this.mapKeyFn(key);
10302
- const matches = this.inner[id];
10303
- if (matches === undefined) {
10304
- return false;
10305
- }
10306
- for (let i = 0; i < matches.length; i++) {
10307
- if (this.equalsFn(matches[i][0], key)) {
10308
- if (matches.length === 1) {
10309
- delete this.inner[id];
10310
- }
10311
- else {
10312
- matches.splice(i, 1);
10313
- }
10314
- return true;
10315
- }
10316
- }
10317
- return false;
10318
- }
10319
- forEach(fn) {
10320
- forEach(this.inner, (_, entries) => {
10321
- for (const [k, v] of entries) {
10322
- fn(k, v);
10323
- }
10324
- });
10325
- }
10326
- isEmpty() {
10327
- return isEmpty(this.inner);
10328
- }
10329
- }
10330
-
10331
9837
  /**
10332
9838
  * @license
10333
9839
  * Copyright 2019 Google LLC
@@ -10580,7 +10086,7 @@ class IndexedDbIndexManager {
10580
10086
  return subTargets;
10581
10087
  }
10582
10088
  /**
10583
- * Constructs a key range query on `DbIndexEntry.store` that unions all
10089
+ * Constructs a key range query on `DbIndexEntryStore` that unions all
10584
10090
  * bounds.
10585
10091
  */
10586
10092
  generateIndexRanges(indexId, arrayValues, lowerBounds, lowerBoundInclusive, upperBounds, upperBoundInclusive, notInValues) {
@@ -10732,7 +10238,7 @@ class IndexedDbIndexManager {
10732
10238
  const indexes = indexConfigurationStore(transaction);
10733
10239
  const states = indexStateStore(transaction);
10734
10240
  return (collectionGroup
10735
- ? indexes.loadAll(DbIndexConfiguration.collectionGroupIndex, IDBKeyRange.bound(collectionGroup, collectionGroup))
10241
+ ? indexes.loadAll(DbIndexConfigurationCollectionGroupIndex, IDBKeyRange.bound(collectionGroup, collectionGroup))
10736
10242
  : indexes.loadAll()).next(indexConfigs => {
10737
10243
  const result = [];
10738
10244
  return PersistencePromise.forEach(indexConfigs, (indexConfig) => {
@@ -10762,7 +10268,7 @@ class IndexedDbIndexManager {
10762
10268
  const indexes = indexConfigurationStore(transaction);
10763
10269
  const states = indexStateStore(transaction);
10764
10270
  return this.getNextSequenceNumber(transaction).next(nextSequenceNumber => indexes
10765
- .loadAll(DbIndexConfiguration.collectionGroupIndex, IDBKeyRange.bound(collectionGroup, collectionGroup))
10271
+ .loadAll(DbIndexConfigurationCollectionGroupIndex, IDBKeyRange.bound(collectionGroup, collectionGroup))
10766
10272
  .next(configs => PersistencePromise.forEach(configs, (config) => states.put(toDbIndexState(config.indexId, this.user, nextSequenceNumber, offset)))));
10767
10273
  }
10768
10274
  updateIndexEntries(transaction, documents) {
@@ -10793,7 +10299,13 @@ class IndexedDbIndexManager {
10793
10299
  }
10794
10300
  addIndexEntry(transaction, document, indexEntry) {
10795
10301
  const indexEntries = indexEntriesStore(transaction);
10796
- return indexEntries.put(new DbIndexEntry(indexEntry.indexId, this.uid, indexEntry.arrayValue, indexEntry.directionalValue, encodeResourcePath(document.key.path)));
10302
+ return indexEntries.put({
10303
+ indexId: indexEntry.indexId,
10304
+ uid: this.uid,
10305
+ arrayValue: indexEntry.arrayValue,
10306
+ directionalValue: indexEntry.directionalValue,
10307
+ documentKey: encodeResourcePath(document.key.path)
10308
+ });
10797
10309
  }
10798
10310
  deleteIndexEntry(transaction, document, indexEntry) {
10799
10311
  const indexEntries = indexEntriesStore(transaction);
@@ -10810,7 +10322,7 @@ class IndexedDbIndexManager {
10810
10322
  let results = new SortedSet(indexEntryComparator);
10811
10323
  return indexEntries
10812
10324
  .iterate({
10813
- index: DbIndexEntry.documentKeyIndex,
10325
+ index: DbIndexEntryDocumentKeyIndex,
10814
10326
  range: IDBKeyRange.only([
10815
10327
  fieldIndex.indexId,
10816
10328
  this.uid,
@@ -10864,7 +10376,7 @@ class IndexedDbIndexManager {
10864
10376
  const states = indexStateStore(transaction);
10865
10377
  return states
10866
10378
  .iterate({
10867
- index: DbIndexState.sequenceNumberIndex,
10379
+ index: DbIndexStateSequenceNumberIndex,
10868
10380
  reverse: true,
10869
10381
  range: IDBKeyRange.upperBound([this.uid, Number.MAX_SAFE_INTEGER])
10870
10382
  }, (_, state, controller) => {
@@ -10929,25 +10441,25 @@ class IndexedDbIndexManager {
10929
10441
  * document store.
10930
10442
  */
10931
10443
  function collectionParentsStore(txn) {
10932
- return getStore(txn, DbCollectionParent.store);
10444
+ return getStore(txn, DbCollectionParentStore);
10933
10445
  }
10934
10446
  /**
10935
10447
  * Helper to get a typed SimpleDbStore for the index entry object store.
10936
10448
  */
10937
10449
  function indexEntriesStore(txn) {
10938
- return getStore(txn, DbIndexEntry.store);
10450
+ return getStore(txn, DbIndexEntryStore);
10939
10451
  }
10940
10452
  /**
10941
10453
  * Helper to get a typed SimpleDbStore for the index configuration object store.
10942
10454
  */
10943
10455
  function indexConfigurationStore(txn) {
10944
- return getStore(txn, DbIndexConfiguration.store);
10456
+ return getStore(txn, DbIndexConfigurationStore);
10945
10457
  }
10946
10458
  /**
10947
10459
  * Helper to get a typed SimpleDbStore for the index state object store.
10948
10460
  */
10949
10461
  function indexStateStore(txn) {
10950
- return getStore(txn, DbIndexState.store);
10462
+ return getStore(txn, DbIndexStateStore);
10951
10463
  }
10952
10464
 
10953
10465
  /**
@@ -10971,8 +10483,8 @@ function indexStateStore(txn) {
10971
10483
  * @returns A PersistencePromise of the document mutations that were removed.
10972
10484
  */
10973
10485
  function removeMutationBatch(txn, userId, batch) {
10974
- const mutationStore = txn.store(DbMutationBatch.store);
10975
- const indexTxn = txn.store(DbDocumentMutation.store);
10486
+ const mutationStore = txn.store(DbMutationBatchStore);
10487
+ const indexTxn = txn.store(DbDocumentMutationStore);
10976
10488
  const promises = [];
10977
10489
  const range = IDBKeyRange.only(batch.batchId);
10978
10490
  let numDeleted = 0;
@@ -10985,7 +10497,7 @@ function removeMutationBatch(txn, userId, batch) {
10985
10497
  }));
10986
10498
  const removedDocuments = [];
10987
10499
  for (const mutation of batch.mutations) {
10988
- const indexKey = DbDocumentMutation.key(userId, mutation.key.path, batch.batchId);
10500
+ const indexKey = newDbDocumentMutationKey(userId, mutation.key.path, batch.batchId);
10989
10501
  promises.push(indexTxn.delete(indexKey));
10990
10502
  removedDocuments.push(mutation.key);
10991
10503
  }
@@ -11074,7 +10586,7 @@ class IndexedDbMutationQueue {
11074
10586
  let empty = true;
11075
10587
  const range = IDBKeyRange.bound([this.userId, Number.NEGATIVE_INFINITY], [this.userId, Number.POSITIVE_INFINITY]);
11076
10588
  return mutationsStore(transaction)
11077
- .iterate({ index: DbMutationBatch.userMutationsIndex, range }, (key, value, control) => {
10589
+ .iterate({ index: DbMutationBatchUserMutationsIndex, range }, (key, value, control) => {
11078
10590
  empty = false;
11079
10591
  control.done();
11080
10592
  })
@@ -11099,10 +10611,10 @@ class IndexedDbMutationQueue {
11099
10611
  const promises = [];
11100
10612
  let collectionParents = new SortedSet((l, r) => primitiveComparator(l.canonicalString(), r.canonicalString()));
11101
10613
  for (const mutation of mutations) {
11102
- const indexKey = DbDocumentMutation.key(this.userId, mutation.key.path, batchId);
10614
+ const indexKey = newDbDocumentMutationKey(this.userId, mutation.key.path, batchId);
11103
10615
  collectionParents = collectionParents.add(mutation.key.path.popLast());
11104
10616
  promises.push(mutationStore.put(dbBatch));
11105
- promises.push(documentStore.put(indexKey, DbDocumentMutation.PLACEHOLDER));
10617
+ promises.push(documentStore.put(indexKey, DbDocumentMutationPlaceholder));
11106
10618
  }
11107
10619
  collectionParents.forEach(parent => {
11108
10620
  promises.push(this.indexManager.addToCollectionParentIndex(transaction, parent));
@@ -11153,7 +10665,7 @@ class IndexedDbMutationQueue {
11153
10665
  const range = IDBKeyRange.lowerBound([this.userId, nextBatchId]);
11154
10666
  let foundBatch = null;
11155
10667
  return mutationsStore(transaction)
11156
- .iterate({ index: DbMutationBatch.userMutationsIndex, range }, (key, dbBatch, control) => {
10668
+ .iterate({ index: DbMutationBatchUserMutationsIndex, range }, (key, dbBatch, control) => {
11157
10669
  if (dbBatch.userId === this.userId) {
11158
10670
  hardAssert(dbBatch.batchId >= nextBatchId);
11159
10671
  foundBatch = fromDbMutationBatch(this.serializer, dbBatch);
@@ -11169,7 +10681,7 @@ class IndexedDbMutationQueue {
11169
10681
  ]);
11170
10682
  let batchId = BATCHID_UNKNOWN;
11171
10683
  return mutationsStore(transaction)
11172
- .iterate({ index: DbMutationBatch.userMutationsIndex, range, reverse: true }, (key, dbBatch, control) => {
10684
+ .iterate({ index: DbMutationBatchUserMutationsIndex, range, reverse: true }, (key, dbBatch, control) => {
11173
10685
  batchId = dbBatch.batchId;
11174
10686
  control.done();
11175
10687
  })
@@ -11178,13 +10690,13 @@ class IndexedDbMutationQueue {
11178
10690
  getAllMutationBatches(transaction) {
11179
10691
  const range = IDBKeyRange.bound([this.userId, BATCHID_UNKNOWN], [this.userId, Number.POSITIVE_INFINITY]);
11180
10692
  return mutationsStore(transaction)
11181
- .loadAll(DbMutationBatch.userMutationsIndex, range)
10693
+ .loadAll(DbMutationBatchUserMutationsIndex, range)
11182
10694
  .next(dbBatches => dbBatches.map(dbBatch => fromDbMutationBatch(this.serializer, dbBatch)));
11183
10695
  }
11184
10696
  getAllMutationBatchesAffectingDocumentKey(transaction, documentKey) {
11185
10697
  // Scan the document-mutation index starting with a prefix starting with
11186
10698
  // the given documentKey.
11187
- const indexPrefix = DbDocumentMutation.prefixForPath(this.userId, documentKey.path);
10699
+ const indexPrefix = newDbDocumentMutationPrefixForPath(this.userId, documentKey.path);
11188
10700
  const indexStart = IDBKeyRange.lowerBound(indexPrefix);
11189
10701
  const results = [];
11190
10702
  return documentMutationsStore(transaction)
@@ -11219,7 +10731,7 @@ class IndexedDbMutationQueue {
11219
10731
  let uniqueBatchIDs = new SortedSet(primitiveComparator);
11220
10732
  const promises = [];
11221
10733
  documentKeys.forEach(documentKey => {
11222
- const indexStart = DbDocumentMutation.prefixForPath(this.userId, documentKey.path);
10734
+ const indexStart = newDbDocumentMutationPrefixForPath(this.userId, documentKey.path);
11223
10735
  const range = IDBKeyRange.lowerBound(indexStart);
11224
10736
  const promise = documentMutationsStore(transaction).iterate({ range }, (indexKey, _, control) => {
11225
10737
  const [userID, encodedPath, batchID] = indexKey;
@@ -11255,7 +10767,7 @@ class IndexedDbMutationQueue {
11255
10767
  // Since we don't yet index the actual properties in the mutations, our
11256
10768
  // current approach is to just return all mutation batches that affect
11257
10769
  // documents in the collection being queried.
11258
- const indexPrefix = DbDocumentMutation.prefixForPath(this.userId, queryPath);
10770
+ const indexPrefix = newDbDocumentMutationPrefixForPath(this.userId, queryPath);
11259
10771
  const indexStart = IDBKeyRange.lowerBound(indexPrefix);
11260
10772
  // Collect up unique batchIDs encountered during a scan of the index. Use a
11261
10773
  // SortedSet to accumulate batch IDs so they can be traversed in order in a
@@ -11327,7 +10839,7 @@ class IndexedDbMutationQueue {
11327
10839
  }
11328
10840
  // Verify that there are no entries in the documentMutations index if
11329
10841
  // the queue is empty.
11330
- const startRange = IDBKeyRange.lowerBound(DbDocumentMutation.prefixForUser(this.userId));
10842
+ const startRange = IDBKeyRange.lowerBound(newDbDocumentMutationPrefixForUser(this.userId));
11331
10843
  const danglingMutationReferences = [];
11332
10844
  return documentMutationsStore(txn)
11333
10845
  .iterate({ range: startRange }, (key, _, control) => {
@@ -11355,9 +10867,11 @@ class IndexedDbMutationQueue {
11355
10867
  return mutationQueuesStore(transaction)
11356
10868
  .get(this.userId)
11357
10869
  .next((metadata) => {
11358
- return (metadata ||
11359
- new DbMutationQueue(this.userId, BATCHID_UNKNOWN,
11360
- /*lastStreamToken=*/ ''));
10870
+ return (metadata || {
10871
+ userId: this.userId,
10872
+ lastAcknowledgedBatchId: BATCHID_UNKNOWN,
10873
+ lastStreamToken: ''
10874
+ });
11361
10875
  });
11362
10876
  }
11363
10877
  }
@@ -11366,7 +10880,7 @@ class IndexedDbMutationQueue {
11366
10880
  * mutation for the given key.
11367
10881
  */
11368
10882
  function mutationQueueContainsKey(txn, userId, key) {
11369
- const indexKey = DbDocumentMutation.prefixForPath(userId, key.path);
10883
+ const indexKey = newDbDocumentMutationPrefixForPath(userId, key.path);
11370
10884
  const encodedPath = indexKey[1];
11371
10885
  const startRange = IDBKeyRange.lowerBound(indexKey);
11372
10886
  let containsKey = false;
@@ -11398,19 +10912,19 @@ function mutationQueuesContainKey(txn, docKey) {
11398
10912
  * Helper to get a typed SimpleDbStore for the mutations object store.
11399
10913
  */
11400
10914
  function mutationsStore(txn) {
11401
- return getStore(txn, DbMutationBatch.store);
10915
+ return getStore(txn, DbMutationBatchStore);
11402
10916
  }
11403
10917
  /**
11404
10918
  * Helper to get a typed SimpleDbStore for the mutationQueues object store.
11405
10919
  */
11406
10920
  function documentMutationsStore(txn) {
11407
- return getStore(txn, DbDocumentMutation.store);
10921
+ return getStore(txn, DbDocumentMutationStore);
11408
10922
  }
11409
10923
  /**
11410
10924
  * Helper to get a typed SimpleDbStore for the mutationQueues object store.
11411
10925
  */
11412
10926
  function mutationQueuesStore(txn) {
11413
- return getStore(txn, DbMutationQueue.store);
10927
+ return getStore(txn, DbMutationQueueStore);
11414
10928
  }
11415
10929
 
11416
10930
  /**
@@ -11574,14 +11088,14 @@ class IndexedDbTargetCache {
11574
11088
  }
11575
11089
  retrieveMetadata(transaction) {
11576
11090
  return globalTargetStore(transaction)
11577
- .get(DbTargetGlobal.key)
11091
+ .get(DbTargetGlobalKey)
11578
11092
  .next(metadata => {
11579
11093
  hardAssert(metadata !== null);
11580
11094
  return metadata;
11581
11095
  });
11582
11096
  }
11583
11097
  saveMetadata(transaction, metadata) {
11584
- return globalTargetStore(transaction).put(DbTargetGlobal.key, metadata);
11098
+ return globalTargetStore(transaction).put(DbTargetGlobalKey, metadata);
11585
11099
  }
11586
11100
  saveTargetData(transaction, targetData) {
11587
11101
  return targetsStore(transaction).put(toDbTarget(this.serializer, targetData));
@@ -11614,7 +11128,7 @@ class IndexedDbTargetCache {
11614
11128
  const range = IDBKeyRange.bound([canonicalId, Number.NEGATIVE_INFINITY], [canonicalId, Number.POSITIVE_INFINITY]);
11615
11129
  let result = null;
11616
11130
  return targetsStore(transaction)
11617
- .iterate({ range, index: DbTarget.queryTargetsIndexName }, (key, value, control) => {
11131
+ .iterate({ range, index: DbTargetQueryTargetsIndexName }, (key, value, control) => {
11618
11132
  const found = fromDbTarget(value);
11619
11133
  // After finding a potential match, check that the target is
11620
11134
  // actually equal to the requested target.
@@ -11632,7 +11146,7 @@ class IndexedDbTargetCache {
11632
11146
  const store = documentTargetStore(txn);
11633
11147
  keys.forEach(key => {
11634
11148
  const path = encodeResourcePath(key.path);
11635
- promises.push(store.put(new DbTargetDocument(targetId, path)));
11149
+ promises.push(store.put({ targetId, path }));
11636
11150
  promises.push(this.referenceDelegate.addReference(txn, targetId, key));
11637
11151
  });
11638
11152
  return PersistencePromise.waitFor(promises);
@@ -11678,7 +11192,7 @@ class IndexedDbTargetCache {
11678
11192
  let count = 0;
11679
11193
  return documentTargetStore(txn)
11680
11194
  .iterate({
11681
- index: DbTargetDocument.documentTargetsIndex,
11195
+ index: DbTargetDocumentDocumentTargetsIndex,
11682
11196
  keysOnly: true,
11683
11197
  range
11684
11198
  }, ([targetId, path], _, control) => {
@@ -11717,19 +11231,19 @@ class IndexedDbTargetCache {
11717
11231
  * Helper to get a typed SimpleDbStore for the queries object store.
11718
11232
  */
11719
11233
  function targetsStore(txn) {
11720
- return getStore(txn, DbTarget.store);
11234
+ return getStore(txn, DbTargetStore);
11721
11235
  }
11722
11236
  /**
11723
11237
  * Helper to get a typed SimpleDbStore for the target globals object store.
11724
11238
  */
11725
11239
  function globalTargetStore(txn) {
11726
- return getStore(txn, DbTargetGlobal.store);
11240
+ return getStore(txn, DbTargetGlobalStore);
11727
11241
  }
11728
11242
  /**
11729
11243
  * Helper to get a typed SimpleDbStore for the document target object store.
11730
11244
  */
11731
11245
  function documentTargetStore(txn) {
11732
- return getStore(txn, DbTargetDocument.store);
11246
+ return getStore(txn, DbTargetDocumentStore);
11733
11247
  }
11734
11248
 
11735
11249
  /**
@@ -12143,7 +11657,7 @@ class IndexedDbLruDelegateImpl {
12143
11657
  let nextPath;
12144
11658
  return store
12145
11659
  .iterate({
12146
- index: DbTargetDocument.documentTargetsIndex
11660
+ index: DbTargetDocumentDocumentTargetsIndex
12147
11661
  }, ([targetId, docKey], { path, sequenceNumber }) => {
12148
11662
  if (targetId === 0) {
12149
11663
  // if nextToReport is valid, report it, this is a new key so the
@@ -12185,7 +11699,7 @@ function sentinelKey$1(key) {
12185
11699
  * store.
12186
11700
  */
12187
11701
  function sentinelRow(key, sequenceNumber) {
12188
- return new DbTargetDocument(0, encodeResourcePath(key.path), sequenceNumber);
11702
+ return { targetId: 0, path: encodeResourcePath(key.path), sequenceNumber };
12189
11703
  }
12190
11704
  function writeSentinelKey(txn, key) {
12191
11705
  return documentTargetStore(txn).put(sentinelRow(key, txn.currentSequenceNumber));
@@ -12459,7 +11973,7 @@ class IndexedDbRemoteDocumentCacheImpl {
12459
11973
  const readTimeKey = toDbTimestampKey(sinceReadTime);
12460
11974
  iterationOptions.range = IDBKeyRange.lowerBound([collectionKey, readTimeKey],
12461
11975
  /* open= */ true);
12462
- iterationOptions.index = DbRemoteDocument.collectionReadTimeIndex;
11976
+ iterationOptions.index = DbRemoteDocumentCollectionReadTimeIndex;
12463
11977
  }
12464
11978
  return remoteDocumentsStore(transaction)
12465
11979
  .iterate(iterationOptions, (key, dbRemoteDoc, control) => {
@@ -12489,14 +12003,14 @@ class IndexedDbRemoteDocumentCacheImpl {
12489
12003
  }
12490
12004
  getMetadata(txn) {
12491
12005
  return documentGlobalStore(txn)
12492
- .get(DbRemoteDocumentGlobal.key)
12006
+ .get(DbRemoteDocumentGlobalKey)
12493
12007
  .next(metadata => {
12494
12008
  hardAssert(!!metadata);
12495
12009
  return metadata;
12496
12010
  });
12497
12011
  }
12498
12012
  setMetadata(txn, metadata) {
12499
- return documentGlobalStore(txn).put(DbRemoteDocumentGlobal.key, metadata);
12013
+ return documentGlobalStore(txn).put(DbRemoteDocumentGlobalKey, metadata);
12500
12014
  }
12501
12015
  /**
12502
12016
  * Decodes `dbRemoteDoc` and returns the document (or an invalid document if
@@ -12531,7 +12045,7 @@ function remoteDocumentCacheGetNewDocumentChanges(remoteDocumentCache, transacti
12531
12045
  const documentsStore = remoteDocumentsStore(transaction);
12532
12046
  const range = IDBKeyRange.lowerBound(lastReadTime, true);
12533
12047
  return documentsStore
12534
- .iterate({ index: DbRemoteDocument.readTimeIndex, range }, (_, dbRemoteDoc) => {
12048
+ .iterate({ index: DbRemoteDocumentReadTimeIndex, range }, (_, dbRemoteDoc) => {
12535
12049
  // Unlike `getEntry()` and others, `getNewDocumentChanges()` parses
12536
12050
  // the documents directly since we want to keep sentinel deletes.
12537
12051
  const doc = fromDbRemoteDocument(remoteDocumentCacheImpl.serializer, dbRemoteDoc);
@@ -12555,7 +12069,7 @@ function remoteDocumentCacheGetLastReadTime(transaction) {
12555
12069
  // If there are no existing entries, we return SnapshotVersion.min().
12556
12070
  let readTime = SnapshotVersion.min();
12557
12071
  return documentsStore
12558
- .iterate({ index: DbRemoteDocument.readTimeIndex, reverse: true }, (key, dbRemoteDoc, control) => {
12072
+ .iterate({ index: DbRemoteDocumentReadTimeIndex, reverse: true }, (key, dbRemoteDoc, control) => {
12559
12073
  if (dbRemoteDoc.readTime) {
12560
12074
  readTime = fromDbTimestampKey(dbRemoteDoc.readTime);
12561
12075
  }
@@ -12643,17 +12157,39 @@ class IndexedDbRemoteDocumentChangeBuffer extends RemoteDocumentChangeBuffer {
12643
12157
  }
12644
12158
  }
12645
12159
  function documentGlobalStore(txn) {
12646
- return getStore(txn, DbRemoteDocumentGlobal.store);
12160
+ return getStore(txn, DbRemoteDocumentGlobalStore);
12647
12161
  }
12648
12162
  /**
12649
12163
  * Helper to get a typed SimpleDbStore for the remoteDocuments object store.
12650
12164
  */
12651
12165
  function remoteDocumentsStore(txn) {
12652
- return getStore(txn, DbRemoteDocument.store);
12166
+ return getStore(txn, DbRemoteDocumentStore);
12653
12167
  }
12654
12168
  function dbKey(docKey) {
12655
12169
  return docKey.path.toArray();
12656
12170
  }
12171
+ /**
12172
+ * Schema Version for the Web client:
12173
+ * 1. Initial version including Mutation Queue, Query Cache, and Remote
12174
+ * Document Cache
12175
+ * 2. Used to ensure a targetGlobal object exists and add targetCount to it. No
12176
+ * longer required because migration 3 unconditionally clears it.
12177
+ * 3. Dropped and re-created Query Cache to deal with cache corruption related
12178
+ * to limbo resolution. Addresses
12179
+ * https://github.com/firebase/firebase-ios-sdk/issues/1548
12180
+ * 4. Multi-Tab Support.
12181
+ * 5. Removal of held write acks.
12182
+ * 6. Create document global for tracking document cache size.
12183
+ * 7. Ensure every cached document has a sentinel row with a sequence number.
12184
+ * 8. Add collection-parent index for Collection Group queries.
12185
+ * 9. Change RemoteDocumentChanges store to be keyed by readTime rather than
12186
+ * an auto-incrementing ID. This is required for Index-Free queries.
12187
+ * 10. Rewrite the canonical IDs to the explicit Protobuf-based format.
12188
+ * 11. Add bundles and named_queries for bundle support.
12189
+ * 12. Add document overlays.
12190
+ * 13. Add indexing support.
12191
+ */
12192
+ const SCHEMA_VERSION = 12;
12657
12193
 
12658
12194
  /**
12659
12195
  * @license
@@ -12763,27 +12299,27 @@ class SchemaConverter {
12763
12299
  return p;
12764
12300
  }
12765
12301
  addDocumentGlobal(txn) {
12766
- let byteCount = 0;
12302
+ let byteSize = 0;
12767
12303
  return txn
12768
- .store(DbRemoteDocument.store)
12304
+ .store(DbRemoteDocumentStore)
12769
12305
  .iterate((_, doc) => {
12770
- byteCount += dbDocumentSize(doc);
12306
+ byteSize += dbDocumentSize(doc);
12771
12307
  })
12772
12308
  .next(() => {
12773
- const metadata = new DbRemoteDocumentGlobal(byteCount);
12309
+ const metadata = { byteSize };
12774
12310
  return txn
12775
- .store(DbRemoteDocumentGlobal.store)
12776
- .put(DbRemoteDocumentGlobal.key, metadata);
12311
+ .store(DbRemoteDocumentGlobalStore)
12312
+ .put(DbRemoteDocumentGlobalKey, metadata);
12777
12313
  });
12778
12314
  }
12779
12315
  removeAcknowledgedMutations(txn) {
12780
- const queuesStore = txn.store(DbMutationQueue.store);
12781
- const mutationsStore = txn.store(DbMutationBatch.store);
12316
+ const queuesStore = txn.store(DbMutationQueueStore);
12317
+ const mutationsStore = txn.store(DbMutationBatchStore);
12782
12318
  return queuesStore.loadAll().next(queues => {
12783
12319
  return PersistencePromise.forEach(queues, (queue) => {
12784
12320
  const range = IDBKeyRange.bound([queue.userId, BATCHID_UNKNOWN], [queue.userId, queue.lastAcknowledgedBatchId]);
12785
12321
  return mutationsStore
12786
- .loadAll(DbMutationBatch.userMutationsIndex, range)
12322
+ .loadAll(DbMutationBatchUserMutationsIndex, range)
12787
12323
  .next(dbBatches => {
12788
12324
  return PersistencePromise.forEach(dbBatches, (dbBatch) => {
12789
12325
  hardAssert(dbBatch.userId === queue.userId);
@@ -12799,12 +12335,16 @@ class SchemaConverter {
12799
12335
  * with a sequence number. Missing rows are given the most recently used sequence number.
12800
12336
  */
12801
12337
  ensureSequenceNumbers(txn) {
12802
- const documentTargetStore = txn.store(DbTargetDocument.store);
12803
- const documentsStore = txn.store(DbRemoteDocument.store);
12804
- const globalTargetStore = txn.store(DbTargetGlobal.store);
12805
- return globalTargetStore.get(DbTargetGlobal.key).next(metadata => {
12338
+ const documentTargetStore = txn.store(DbTargetDocumentStore);
12339
+ const documentsStore = txn.store(DbRemoteDocumentStore);
12340
+ const globalTargetStore = txn.store(DbTargetGlobalStore);
12341
+ return globalTargetStore.get(DbTargetGlobalKey).next(metadata => {
12806
12342
  const writeSentinelKey = (path) => {
12807
- return documentTargetStore.put(new DbTargetDocument(0, encodeResourcePath(path), metadata.highestListenSequenceNumber));
12343
+ return documentTargetStore.put({
12344
+ targetId: 0,
12345
+ path: encodeResourcePath(path),
12346
+ sequenceNumber: metadata.highestListenSequenceNumber
12347
+ });
12808
12348
  };
12809
12349
  const promises = [];
12810
12350
  return documentsStore
@@ -12825,10 +12365,10 @@ class SchemaConverter {
12825
12365
  }
12826
12366
  createCollectionParentIndex(db, txn) {
12827
12367
  // Create the index.
12828
- db.createObjectStore(DbCollectionParent.store, {
12829
- keyPath: DbCollectionParent.keyPath
12368
+ db.createObjectStore(DbCollectionParentStore, {
12369
+ keyPath: DbCollectionParentKeyPath
12830
12370
  });
12831
- const collectionParentsStore = txn.store(DbCollectionParent.store);
12371
+ const collectionParentsStore = txn.store(DbCollectionParentStore);
12832
12372
  // Helper to add an index entry iff we haven't already written it.
12833
12373
  const cache = new MemoryCollectionParentIndex();
12834
12374
  const addEntry = (collectionPath) => {
@@ -12843,7 +12383,7 @@ class SchemaConverter {
12843
12383
  };
12844
12384
  // Index existing remote documents.
12845
12385
  return txn
12846
- .store(DbRemoteDocument.store)
12386
+ .store(DbRemoteDocumentStore)
12847
12387
  .iterate({ keysOnly: true }, (pathSegments, _) => {
12848
12388
  const path = new ResourcePath(pathSegments);
12849
12389
  return addEntry(path.popLast());
@@ -12851,7 +12391,7 @@ class SchemaConverter {
12851
12391
  .next(() => {
12852
12392
  // Index existing mutations.
12853
12393
  return txn
12854
- .store(DbDocumentMutation.store)
12394
+ .store(DbDocumentMutationStore)
12855
12395
  .iterate({ keysOnly: true }, ([userID, encodedPath, batchId], _) => {
12856
12396
  const path = decodeResourcePath(encodedPath);
12857
12397
  return addEntry(path.popLast());
@@ -12859,7 +12399,7 @@ class SchemaConverter {
12859
12399
  });
12860
12400
  }
12861
12401
  rewriteCanonicalIds(txn) {
12862
- const targetStore = txn.store(DbTarget.store);
12402
+ const targetStore = txn.store(DbTargetStore);
12863
12403
  return targetStore.iterate((key, originalDbTarget) => {
12864
12404
  const originalTargetData = fromDbTarget(originalDbTarget);
12865
12405
  const updatedDbTarget = toDbTarget(this.serializer, originalTargetData);
@@ -12871,59 +12411,59 @@ function sentinelKey(path) {
12871
12411
  return [0, encodeResourcePath(path)];
12872
12412
  }
12873
12413
  function createPrimaryClientStore(db) {
12874
- db.createObjectStore(DbPrimaryClient.store);
12414
+ db.createObjectStore(DbPrimaryClientStore);
12875
12415
  }
12876
12416
  function createMutationQueue(db) {
12877
- db.createObjectStore(DbMutationQueue.store, {
12878
- keyPath: DbMutationQueue.keyPath
12417
+ db.createObjectStore(DbMutationQueueStore, {
12418
+ keyPath: DbMutationQueueKeyPath
12879
12419
  });
12880
- const mutationBatchesStore = db.createObjectStore(DbMutationBatch.store, {
12881
- keyPath: DbMutationBatch.keyPath,
12420
+ const mutationBatchesStore = db.createObjectStore(DbMutationBatchStore, {
12421
+ keyPath: DbMutationBatchKeyPath,
12882
12422
  autoIncrement: true
12883
12423
  });
12884
- mutationBatchesStore.createIndex(DbMutationBatch.userMutationsIndex, DbMutationBatch.userMutationsKeyPath, { unique: true });
12885
- db.createObjectStore(DbDocumentMutation.store);
12424
+ mutationBatchesStore.createIndex(DbMutationBatchUserMutationsIndex, DbMutationBatchUserMutationsKeyPath, { unique: true });
12425
+ db.createObjectStore(DbDocumentMutationStore);
12886
12426
  }
12887
12427
  /**
12888
12428
  * Upgrade function to migrate the 'mutations' store from V1 to V3. Loads
12889
12429
  * and rewrites all data.
12890
12430
  */
12891
12431
  function upgradeMutationBatchSchemaAndMigrateData(db, txn) {
12892
- const v1MutationsStore = txn.store(DbMutationBatch.store);
12432
+ const v1MutationsStore = txn.store(DbMutationBatchStore);
12893
12433
  return v1MutationsStore.loadAll().next(existingMutations => {
12894
- db.deleteObjectStore(DbMutationBatch.store);
12895
- const mutationsStore = db.createObjectStore(DbMutationBatch.store, {
12896
- keyPath: DbMutationBatch.keyPath,
12434
+ db.deleteObjectStore(DbMutationBatchStore);
12435
+ const mutationsStore = db.createObjectStore(DbMutationBatchStore, {
12436
+ keyPath: DbMutationBatchKeyPath,
12897
12437
  autoIncrement: true
12898
12438
  });
12899
- mutationsStore.createIndex(DbMutationBatch.userMutationsIndex, DbMutationBatch.userMutationsKeyPath, { unique: true });
12900
- const v3MutationsStore = txn.store(DbMutationBatch.store);
12439
+ mutationsStore.createIndex(DbMutationBatchUserMutationsIndex, DbMutationBatchUserMutationsKeyPath, { unique: true });
12440
+ const v3MutationsStore = txn.store(DbMutationBatchStore);
12901
12441
  const writeAll = existingMutations.map(mutation => v3MutationsStore.put(mutation));
12902
12442
  return PersistencePromise.waitFor(writeAll);
12903
12443
  });
12904
12444
  }
12905
12445
  function createRemoteDocumentCache(db) {
12906
- db.createObjectStore(DbRemoteDocument.store);
12446
+ db.createObjectStore(DbRemoteDocumentStore);
12907
12447
  }
12908
12448
  function createDocumentGlobalStore(db) {
12909
- db.createObjectStore(DbRemoteDocumentGlobal.store);
12449
+ db.createObjectStore(DbRemoteDocumentGlobalStore);
12910
12450
  }
12911
12451
  function createQueryCache(db) {
12912
- const targetDocumentsStore = db.createObjectStore(DbTargetDocument.store, {
12913
- keyPath: DbTargetDocument.keyPath
12452
+ const targetDocumentsStore = db.createObjectStore(DbTargetDocumentStore, {
12453
+ keyPath: DbTargetDocumentKeyPath
12914
12454
  });
12915
- targetDocumentsStore.createIndex(DbTargetDocument.documentTargetsIndex, DbTargetDocument.documentTargetsKeyPath, { unique: true });
12916
- const targetStore = db.createObjectStore(DbTarget.store, {
12917
- keyPath: DbTarget.keyPath
12455
+ targetDocumentsStore.createIndex(DbTargetDocumentDocumentTargetsIndex, DbTargetDocumentDocumentTargetsKeyPath, { unique: true });
12456
+ const targetStore = db.createObjectStore(DbTargetStore, {
12457
+ keyPath: DbTargetKeyPath
12918
12458
  });
12919
12459
  // NOTE: This is unique only because the TargetId is the suffix.
12920
- targetStore.createIndex(DbTarget.queryTargetsIndexName, DbTarget.queryTargetsKeyPath, { unique: true });
12921
- db.createObjectStore(DbTargetGlobal.store);
12460
+ targetStore.createIndex(DbTargetQueryTargetsIndexName, DbTargetQueryTargetsKeyPath, { unique: true });
12461
+ db.createObjectStore(DbTargetGlobalStore);
12922
12462
  }
12923
12463
  function dropQueryCache(db) {
12924
- db.deleteObjectStore(DbTargetDocument.store);
12925
- db.deleteObjectStore(DbTarget.store);
12926
- db.deleteObjectStore(DbTargetGlobal.store);
12464
+ db.deleteObjectStore(DbTargetDocumentStore);
12465
+ db.deleteObjectStore(DbTargetStore);
12466
+ db.deleteObjectStore(DbTargetGlobalStore);
12927
12467
  }
12928
12468
  function dropRemoteDocumentChangesStore(db) {
12929
12469
  if (db.objectStoreNames.contains('remoteDocumentChanges')) {
@@ -12936,58 +12476,60 @@ function dropRemoteDocumentChangesStore(db) {
12936
12476
  * @param txn - The version upgrade transaction for indexeddb
12937
12477
  */
12938
12478
  function writeEmptyTargetGlobalEntry(txn) {
12939
- const globalStore = txn.store(DbTargetGlobal.store);
12940
- const metadata = new DbTargetGlobal(
12941
- /*highestTargetId=*/ 0,
12942
- /*lastListenSequenceNumber=*/ 0, SnapshotVersion.min().toTimestamp(),
12943
- /*targetCount=*/ 0);
12944
- return globalStore.put(DbTargetGlobal.key, metadata);
12479
+ const globalStore = txn.store(DbTargetGlobalStore);
12480
+ const metadata = {
12481
+ highestTargetId: 0,
12482
+ highestListenSequenceNumber: 0,
12483
+ lastRemoteSnapshotVersion: SnapshotVersion.min().toTimestamp(),
12484
+ targetCount: 0
12485
+ };
12486
+ return globalStore.put(DbTargetGlobalKey, metadata);
12945
12487
  }
12946
12488
  /**
12947
12489
  * Creates indices on the RemoteDocuments store used for both multi-tab
12948
12490
  * and Index-Free queries.
12949
12491
  */
12950
12492
  function createRemoteDocumentReadTimeIndex(txn) {
12951
- const remoteDocumentStore = txn.objectStore(DbRemoteDocument.store);
12952
- remoteDocumentStore.createIndex(DbRemoteDocument.readTimeIndex, DbRemoteDocument.readTimeIndexPath, { unique: false });
12953
- remoteDocumentStore.createIndex(DbRemoteDocument.collectionReadTimeIndex, DbRemoteDocument.collectionReadTimeIndexPath, { unique: false });
12493
+ const remoteDocumentStore = txn.objectStore(DbRemoteDocumentStore);
12494
+ remoteDocumentStore.createIndex(DbRemoteDocumentReadTimeIndex, DbRemoteDocumentReadTimeIndexPath, { unique: false });
12495
+ remoteDocumentStore.createIndex(DbRemoteDocumentCollectionReadTimeIndex, DbRemoteDocumentCollectionReadTimeIndexPath, { unique: false });
12954
12496
  }
12955
12497
  function createClientMetadataStore(db) {
12956
- db.createObjectStore(DbClientMetadata.store, {
12957
- keyPath: DbClientMetadata.keyPath
12498
+ db.createObjectStore(DbClientMetadataStore, {
12499
+ keyPath: DbClientMetadataKeyPath
12958
12500
  });
12959
12501
  }
12960
12502
  function createBundlesStore(db) {
12961
- db.createObjectStore(DbBundle.store, {
12962
- keyPath: DbBundle.keyPath
12503
+ db.createObjectStore(DbBundleStore, {
12504
+ keyPath: DbBundleKeyPath
12963
12505
  });
12964
12506
  }
12965
12507
  function createNamedQueriesStore(db) {
12966
- db.createObjectStore(DbNamedQuery.store, {
12967
- keyPath: DbNamedQuery.keyPath
12508
+ db.createObjectStore(DbNamedQueryStore, {
12509
+ keyPath: DbNamedQueryKeyPath
12968
12510
  });
12969
12511
  }
12970
12512
  function createFieldIndex(db) {
12971
- const indexConfiguratioStore = db.createObjectStore(DbIndexConfiguration.store, {
12972
- keyPath: DbIndexConfiguration.keyPath,
12513
+ const indexConfiguratioStore = db.createObjectStore(DbIndexConfigurationStore, {
12514
+ keyPath: DbIndexConfigurationKeyPath,
12973
12515
  autoIncrement: true
12974
12516
  });
12975
- indexConfiguratioStore.createIndex(DbIndexConfiguration.collectionGroupIndex, DbIndexConfiguration.collectionGroupIndexPath, { unique: false });
12976
- const indexStateStore = db.createObjectStore(DbIndexState.store, {
12977
- keyPath: DbIndexState.keyPath
12517
+ indexConfiguratioStore.createIndex(DbIndexConfigurationCollectionGroupIndex, DbIndexConfigurationCollectionGroupIndexPath, { unique: false });
12518
+ const indexStateStore = db.createObjectStore(DbIndexStateStore, {
12519
+ keyPath: DbIndexStateKeyPath
12978
12520
  });
12979
- indexStateStore.createIndex(DbIndexState.sequenceNumberIndex, DbIndexState.sequenceNumberIndexPath, { unique: false });
12980
- const indexEntryStore = db.createObjectStore(DbIndexEntry.store, {
12981
- keyPath: DbIndexEntry.keyPath
12521
+ indexStateStore.createIndex(DbIndexStateSequenceNumberIndex, DbIndexStateSequenceNumberIndexPath, { unique: false });
12522
+ const indexEntryStore = db.createObjectStore(DbIndexEntryStore, {
12523
+ keyPath: DbIndexEntryKeyPath
12982
12524
  });
12983
- indexEntryStore.createIndex(DbIndexEntry.documentKeyIndex, DbIndexEntry.documentKeyIndexPath, { unique: false });
12525
+ indexEntryStore.createIndex(DbIndexEntryDocumentKeyIndex, DbIndexEntryDocumentKeyIndexPath, { unique: false });
12984
12526
  }
12985
12527
  function createDocumentOverlayStore(db) {
12986
- const documentOverlayStore = db.createObjectStore(DbDocumentOverlay.store, {
12987
- keyPath: DbDocumentOverlay.keyPath
12528
+ const documentOverlayStore = db.createObjectStore(DbDocumentOverlayStore, {
12529
+ keyPath: DbDocumentOverlayKeyPath
12988
12530
  });
12989
- documentOverlayStore.createIndex(DbDocumentOverlay.collectionPathOverlayIndex, DbDocumentOverlay.collectionPathOverlayIndexPath, { unique: false });
12990
- documentOverlayStore.createIndex(DbDocumentOverlay.collectionGroupOverlayIndex, DbDocumentOverlay.collectionGroupOverlayIndexPath, { unique: false });
12531
+ documentOverlayStore.createIndex(DbDocumentOverlayCollectionPathOverlayIndex, DbDocumentOverlayCollectionPathOverlayIndexPath, { unique: false });
12532
+ documentOverlayStore.createIndex(DbDocumentOverlayCollectionGroupOverlayIndex, DbDocumentOverlayCollectionGroupOverlayIndexPath, { unique: false });
12991
12533
  }
12992
12534
 
12993
12535
  /**
@@ -13235,7 +12777,12 @@ class IndexedDbPersistence {
13235
12777
  return this.runTransaction('updateClientMetadataAndTryBecomePrimary', 'readwrite', txn => {
13236
12778
  const metadataStore = clientMetadataStore(txn);
13237
12779
  return metadataStore
13238
- .put(new DbClientMetadata(this.clientId, Date.now(), this.networkEnabled, this.inForeground))
12780
+ .put({
12781
+ clientId: this.clientId,
12782
+ updateTimeMs: Date.now(),
12783
+ networkEnabled: this.networkEnabled,
12784
+ inForeground: this.inForeground
12785
+ })
13239
12786
  .next(() => {
13240
12787
  if (this.isPrimary) {
13241
12788
  return this.verifyPrimaryLease(txn).next(success => {
@@ -13281,7 +12828,7 @@ class IndexedDbPersistence {
13281
12828
  }
13282
12829
  verifyPrimaryLease(txn) {
13283
12830
  const store = primaryClientStore(txn);
13284
- return store.get(DbPrimaryClient.key).next(primaryClient => {
12831
+ return store.get(DbPrimaryClientKey).next(primaryClient => {
13285
12832
  return PersistencePromise.resolve(this.isLocalClient(primaryClient));
13286
12833
  });
13287
12834
  }
@@ -13299,7 +12846,7 @@ class IndexedDbPersistence {
13299
12846
  !this.isWithinAge(this.lastGarbageCollectionTime, MAX_CLIENT_AGE_MS)) {
13300
12847
  this.lastGarbageCollectionTime = Date.now();
13301
12848
  const inactiveClients = await this.runTransaction('maybeGarbageCollectMultiClientState', 'readwrite-primary', txn => {
13302
- const metadataStore = getStore(txn, DbClientMetadata.store);
12849
+ const metadataStore = getStore(txn, DbClientMetadataStore);
13303
12850
  return metadataStore.loadAll().next(existingClients => {
13304
12851
  const active = this.filterActiveClients(existingClients, MAX_CLIENT_AGE_MS);
13305
12852
  const inactive = existingClients.filter(client => active.indexOf(client) === -1);
@@ -13353,7 +12900,7 @@ class IndexedDbPersistence {
13353
12900
  }
13354
12901
  const store = primaryClientStore(txn);
13355
12902
  return store
13356
- .get(DbPrimaryClient.key)
12903
+ .get(DbPrimaryClientKey)
13357
12904
  .next(currentPrimary => {
13358
12905
  const currentLeaseIsValid = currentPrimary !== null &&
13359
12906
  this.isWithinAge(currentPrimary.leaseTimestampMs, MAX_PRIMARY_ELIGIBLE_AGE_MS) &&
@@ -13434,7 +12981,7 @@ class IndexedDbPersistence {
13434
12981
  this.detachWindowUnloadHook();
13435
12982
  // Use `SimpleDb.runTransaction` directly to avoid failing if another tab
13436
12983
  // has obtained the primary lease.
13437
- await this.simpleDb.runTransaction('shutdown', 'readwrite', [DbPrimaryClient.store, DbClientMetadata.store], simpleDbTxn => {
12984
+ await this.simpleDb.runTransaction('shutdown', 'readwrite', [DbPrimaryClientStore, DbClientMetadataStore], simpleDbTxn => {
13438
12985
  const persistenceTransaction = new IndexedDbTransaction(simpleDbTxn, ListenSequence.INVALID);
13439
12986
  return this.releasePrimaryLeaseIfHeld(persistenceTransaction).next(() => this.removeClientMetadata(persistenceTransaction));
13440
12987
  });
@@ -13541,7 +13088,7 @@ class IndexedDbPersistence {
13541
13088
  // be turned off.
13542
13089
  verifyAllowTabSynchronization(txn) {
13543
13090
  const store = primaryClientStore(txn);
13544
- return store.get(DbPrimaryClient.key).next(currentPrimary => {
13091
+ return store.get(DbPrimaryClientKey).next(currentPrimary => {
13545
13092
  const currentLeaseIsValid = currentPrimary !== null &&
13546
13093
  this.isWithinAge(currentPrimary.leaseTimestampMs, MAX_PRIMARY_ELIGIBLE_AGE_MS) &&
13547
13094
  !this.isClientZombied(currentPrimary.ownerId);
@@ -13559,8 +13106,12 @@ class IndexedDbPersistence {
13559
13106
  * method does not verify that the client is eligible for this lease.
13560
13107
  */
13561
13108
  acquireOrExtendPrimaryLease(txn) {
13562
- const newPrimary = new DbPrimaryClient(this.clientId, this.allowTabSynchronization, Date.now());
13563
- return primaryClientStore(txn).put(DbPrimaryClient.key, newPrimary);
13109
+ const newPrimary = {
13110
+ ownerId: this.clientId,
13111
+ allowTabSynchronization: this.allowTabSynchronization,
13112
+ leaseTimestampMs: Date.now()
13113
+ };
13114
+ return primaryClientStore(txn).put(DbPrimaryClientKey, newPrimary);
13564
13115
  }
13565
13116
  static isAvailable() {
13566
13117
  return SimpleDb.isAvailable();
@@ -13568,10 +13119,10 @@ class IndexedDbPersistence {
13568
13119
  /** Checks the primary lease and removes it if we are the current primary. */
13569
13120
  releasePrimaryLeaseIfHeld(txn) {
13570
13121
  const store = primaryClientStore(txn);
13571
- return store.get(DbPrimaryClient.key).next(primaryClient => {
13122
+ return store.get(DbPrimaryClientKey).next(primaryClient => {
13572
13123
  if (this.isLocalClient(primaryClient)) {
13573
13124
  logDebug(LOG_TAG$d, 'Releasing primary lease.');
13574
- return store.delete(DbPrimaryClient.key);
13125
+ return store.delete(DbPrimaryClientKey);
13575
13126
  }
13576
13127
  else {
13577
13128
  return PersistencePromise.resolve();
@@ -13705,13 +13256,13 @@ class IndexedDbPersistence {
13705
13256
  * Helper to get a typed SimpleDbStore for the primary client object store.
13706
13257
  */
13707
13258
  function primaryClientStore(txn) {
13708
- return getStore(txn, DbPrimaryClient.store);
13259
+ return getStore(txn, DbPrimaryClientStore);
13709
13260
  }
13710
13261
  /**
13711
13262
  * Helper to get a typed SimpleDbStore for the client metadata object store.
13712
13263
  */
13713
13264
  function clientMetadataStore(txn) {
13714
- return getStore(txn, DbClientMetadata.store);
13265
+ return getStore(txn, DbClientMetadataStore);
13715
13266
  }
13716
13267
  /**
13717
13268
  * Generates a string used as a prefix when storing data in IndexedDB and
@@ -14774,7 +14325,7 @@ class MemoryDocumentOverlayCache {
14774
14325
  return PersistencePromise.resolve(this.overlays.get(key));
14775
14326
  }
14776
14327
  saveOverlays(transaction, largestBatchId, overlays) {
14777
- overlays.forEach(mutation => {
14328
+ overlays.forEach((_, mutation) => {
14778
14329
  this.saveOverlay(transaction, largestBatchId, mutation);
14779
14330
  });
14780
14331
  return PersistencePromise.resolve();
@@ -14788,7 +14339,7 @@ class MemoryDocumentOverlayCache {
14788
14339
  return PersistencePromise.resolve();
14789
14340
  }
14790
14341
  getOverlaysForCollection(transaction, collection, sinceBatchId) {
14791
- const result = new Map();
14342
+ const result = newOverlayMap();
14792
14343
  const immediateChildrenPathLength = collection.length + 1;
14793
14344
  const prefix = new DocumentKey(collection.child(''));
14794
14345
  const iter = this.overlays.getIteratorFrom(prefix);
@@ -14822,19 +14373,19 @@ class MemoryDocumentOverlayCache {
14822
14373
  if (overlay.largestBatchId > sinceBatchId) {
14823
14374
  let overlaysForBatchId = batchIdToOverlays.get(overlay.largestBatchId);
14824
14375
  if (overlaysForBatchId === null) {
14825
- overlaysForBatchId = new Map();
14376
+ overlaysForBatchId = newOverlayMap();
14826
14377
  batchIdToOverlays = batchIdToOverlays.insert(overlay.largestBatchId, overlaysForBatchId);
14827
14378
  }
14828
14379
  overlaysForBatchId.set(overlay.getKey(), overlay);
14829
14380
  }
14830
14381
  }
14831
- const result = new Map();
14382
+ const result = newOverlayMap();
14832
14383
  const batchIter = batchIdToOverlays.getIterator();
14833
14384
  while (batchIter.hasNext()) {
14834
14385
  const entry = batchIter.getNext();
14835
14386
  const overlays = entry.value;
14836
- overlays.forEach((overlay, key) => result.set(key, overlay));
14837
- if (result.size >= count) {
14387
+ overlays.forEach((key, overlay) => result.set(key, overlay));
14388
+ if (result.size() >= count) {
14838
14389
  break;
14839
14390
  }
14840
14391
  }
@@ -14847,16 +14398,19 @@ class MemoryDocumentOverlayCache {
14847
14398
  // Remove the association of the overlay to its batch id.
14848
14399
  const existing = this.overlays.get(mutation.key);
14849
14400
  if (existing !== null) {
14850
- this.overlayByBatchId.get(existing.largestBatchId).delete(mutation.key);
14401
+ const newSet = this.overlayByBatchId
14402
+ .get(existing.largestBatchId)
14403
+ .delete(mutation.key);
14404
+ this.overlayByBatchId.set(existing.largestBatchId, newSet);
14851
14405
  }
14852
14406
  this.overlays = this.overlays.insert(mutation.key, new Overlay(largestBatchId, mutation));
14853
14407
  // Create the association of this overlay to the given largestBatchId.
14854
14408
  let batch = this.overlayByBatchId.get(largestBatchId);
14855
14409
  if (batch === undefined) {
14856
- batch = new Set();
14410
+ batch = documentKeySet();
14857
14411
  this.overlayByBatchId.set(largestBatchId, batch);
14858
14412
  }
14859
- batch.add(mutation.key);
14413
+ this.overlayByBatchId.set(largestBatchId, batch.add(mutation.key));
14860
14414
  }
14861
14415
  }
14862
14416