@firebase/firestore 3.4.7 → 3.4.8-2022312211851

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 (65) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/firestore/src/local/index_manager.d.ts +3 -2
  3. package/dist/firestore/src/local/indexeddb_index_manager.d.ts +11 -3
  4. package/dist/firestore/src/local/indexeddb_remote_document_cache.d.ts +9 -0
  5. package/dist/firestore/src/local/indexeddb_schema.d.ts +7 -2
  6. package/dist/firestore/src/local/indexeddb_sentinels.d.ts +9 -2
  7. package/dist/firestore/src/local/memory_index_manager.d.ts +3 -2
  8. package/dist/firestore/src/local/simple_db.d.ts +2 -0
  9. package/dist/firestore/src/model/field_index.d.ts +6 -0
  10. package/dist/firestore/test/unit/local/test_index_manager.d.ts +3 -2
  11. package/dist/firestore/test/unit/local/test_remote_document_cache.d.ts +0 -4
  12. package/dist/index.esm2017.js +3268 -3209
  13. package/dist/index.esm2017.js.map +1 -1
  14. package/dist/index.esm5.js +3571 -3518
  15. package/dist/index.esm5.js.map +1 -1
  16. package/dist/index.node.cjs.js +192 -124
  17. package/dist/index.node.cjs.js.map +1 -1
  18. package/dist/index.node.mjs +192 -124
  19. package/dist/index.node.mjs.map +1 -1
  20. package/dist/index.rn.js +3089 -3030
  21. package/dist/index.rn.js.map +1 -1
  22. package/dist/internal.d.ts +1 -1
  23. package/dist/lite/firestore/src/local/index_manager.d.ts +3 -2
  24. package/dist/lite/firestore/src/local/indexeddb_index_manager.d.ts +11 -3
  25. package/dist/lite/firestore/src/local/indexeddb_remote_document_cache.d.ts +9 -0
  26. package/dist/lite/firestore/src/local/indexeddb_schema.d.ts +7 -2
  27. package/dist/lite/firestore/src/local/indexeddb_sentinels.d.ts +9 -2
  28. package/dist/lite/firestore/src/local/memory_index_manager.d.ts +3 -2
  29. package/dist/lite/firestore/src/local/simple_db.d.ts +2 -0
  30. package/dist/lite/firestore/src/model/field_index.d.ts +6 -0
  31. package/dist/lite/firestore/test/unit/local/test_index_manager.d.ts +3 -2
  32. package/dist/lite/firestore/test/unit/local/test_remote_document_cache.d.ts +0 -4
  33. package/dist/lite/index.browser.esm2017.js +2 -2
  34. package/dist/lite/index.browser.esm2017.js.map +1 -1
  35. package/dist/lite/index.browser.esm5.js +2 -2
  36. package/dist/lite/index.browser.esm5.js.map +1 -1
  37. package/dist/lite/index.node.cjs.js +2 -2
  38. package/dist/lite/index.node.cjs.js.map +1 -1
  39. package/dist/lite/index.node.mjs +2 -2
  40. package/dist/lite/index.node.mjs.map +1 -1
  41. package/dist/lite/index.rn.esm2017.js +2 -2
  42. package/dist/lite/index.rn.esm2017.js.map +1 -1
  43. package/dist/lite/packages/firestore/src/local/index_manager.d.ts +3 -2
  44. package/dist/lite/packages/firestore/src/local/indexeddb_index_manager.d.ts +11 -3
  45. package/dist/lite/packages/firestore/src/local/indexeddb_remote_document_cache.d.ts +9 -0
  46. package/dist/lite/packages/firestore/src/local/indexeddb_schema.d.ts +7 -2
  47. package/dist/lite/packages/firestore/src/local/indexeddb_sentinels.d.ts +9 -2
  48. package/dist/lite/packages/firestore/src/local/memory_index_manager.d.ts +3 -2
  49. package/dist/lite/packages/firestore/src/local/simple_db.d.ts +2 -0
  50. package/dist/lite/packages/firestore/src/model/field_index.d.ts +6 -0
  51. package/dist/lite/packages/firestore/test/unit/local/test_index_manager.d.ts +3 -2
  52. package/dist/lite/packages/firestore/test/unit/local/test_remote_document_cache.d.ts +0 -4
  53. package/dist/packages/firestore/dist/index.esm2017.d.ts +163 -163
  54. package/dist/packages/firestore/src/local/index_manager.d.ts +3 -2
  55. package/dist/packages/firestore/src/local/indexeddb_index_manager.d.ts +11 -3
  56. package/dist/packages/firestore/src/local/indexeddb_remote_document_cache.d.ts +9 -0
  57. package/dist/packages/firestore/src/local/indexeddb_schema.d.ts +7 -2
  58. package/dist/packages/firestore/src/local/indexeddb_sentinels.d.ts +9 -2
  59. package/dist/packages/firestore/src/local/memory_index_manager.d.ts +3 -2
  60. package/dist/packages/firestore/src/local/simple_db.d.ts +2 -0
  61. package/dist/packages/firestore/src/model/field_index.d.ts +6 -0
  62. package/dist/packages/firestore/test/unit/local/test_index_manager.d.ts +3 -2
  63. package/dist/packages/firestore/test/unit/local/test_remote_document_cache.d.ts +0 -4
  64. package/dist/private.d.ts +1 -1
  65. package/package.json +7 -7
@@ -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.7";
36
+ const version$1 = "3.4.8-2022312211851";
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.10";
89
+ const version = "9.6.11-2022312211851";
90
90
 
91
91
  /**
92
92
  * @license
@@ -1418,13 +1418,14 @@ const DbIndexEntryKeyPath = [
1418
1418
  'uid',
1419
1419
  'arrayValue',
1420
1420
  'directionalValue',
1421
+ 'orderedDocumentKey',
1421
1422
  'documentKey'
1422
1423
  ];
1423
1424
  const DbIndexEntryDocumentKeyIndex = 'documentKeyIndex';
1424
1425
  const DbIndexEntryDocumentKeyIndexPath = [
1425
1426
  'indexId',
1426
1427
  'uid',
1427
- 'documentKey'
1428
+ 'orderedDocumentKey'
1428
1429
  ];
1429
1430
  /** Name of the IndexedDb object store. */
1430
1431
  const DbDocumentOverlayStore = 'documentOverlays';
@@ -2310,9 +2311,7 @@ class SimpleDbStore {
2310
2311
  cursor.continue(controller.skipToKey);
2311
2312
  }
2312
2313
  };
2313
- }).next(() => {
2314
- return PersistencePromise.waitFor(results);
2315
- });
2314
+ }).next(() => PersistencePromise.waitFor(results));
2316
2315
  }
2317
2316
  options(indexOrRange, range) {
2318
2317
  let indexName = undefined;
@@ -4221,6 +4220,17 @@ function fieldIndexGetArraySegment(fieldIndex) {
4221
4220
  function fieldIndexGetDirectionalSegments(fieldIndex) {
4222
4221
  return fieldIndex.fields.filter(s => s.kind !== 2 /* CONTAINS */);
4223
4222
  }
4223
+ /**
4224
+ * Returns the order of the document key component for the given index.
4225
+ *
4226
+ * PORTING NOTE: This is only used in the Web IndexedDb implementation.
4227
+ */
4228
+ function fieldIndexGetKeyOrder(fieldIndex) {
4229
+ const directionalSegments = fieldIndexGetDirectionalSegments(fieldIndex);
4230
+ return directionalSegments.length === 0
4231
+ ? 0 /* ASCENDING */
4232
+ : directionalSegments[directionalSegments.length - 1].kind;
4233
+ }
4224
4234
  /** Returns a debug representation of the field index */
4225
4235
  function fieldIndexToString(fieldIndex) {
4226
4236
  return `id=${fieldIndex.indexId}|cg=${fieldIndex.collectionGroup}|f=${fieldIndex.fields.map(f => `${f.fieldPath}:${f.kind}`).join(',')}`;
@@ -4521,58 +4531,15 @@ function targetGetLowerBound(target, fieldIndex) {
4521
4531
  // For each segment, retrieve a lower bound if there is a suitable filter or
4522
4532
  // startAt.
4523
4533
  for (const segment of fieldIndexGetDirectionalSegments(fieldIndex)) {
4524
- let segmentValue = undefined;
4525
- let segmentInclusive = true;
4526
- // Process all filters to find a value for the current field segment
4527
- for (const fieldFilter of targetGetFieldFiltersForPath(target, segment.fieldPath)) {
4528
- let filterValue = undefined;
4529
- let filterInclusive = true;
4530
- switch (fieldFilter.op) {
4531
- case "<" /* LESS_THAN */:
4532
- case "<=" /* LESS_THAN_OR_EQUAL */:
4533
- filterValue = valuesGetLowerBound(fieldFilter.value);
4534
- break;
4535
- case "==" /* EQUAL */:
4536
- case "in" /* IN */:
4537
- case ">=" /* GREATER_THAN_OR_EQUAL */:
4538
- filterValue = fieldFilter.value;
4539
- break;
4540
- case ">" /* GREATER_THAN */:
4541
- filterValue = fieldFilter.value;
4542
- filterInclusive = false;
4543
- break;
4544
- case "!=" /* NOT_EQUAL */:
4545
- case "not-in" /* NOT_IN */:
4546
- filterValue = MIN_VALUE;
4547
- break;
4548
- // Remaining filters cannot be used as lower bounds.
4549
- }
4550
- if (valuesMax(segmentValue, filterValue) === filterValue) {
4551
- segmentValue = filterValue;
4552
- segmentInclusive = filterInclusive;
4553
- }
4554
- }
4555
- // If there is a startAt bound, compare the values against the existing
4556
- // boundary to see if we can narrow the scope.
4557
- if (target.startAt !== null) {
4558
- for (let i = 0; i < target.orderBy.length; ++i) {
4559
- const orderBy = target.orderBy[i];
4560
- if (orderBy.field.isEqual(segment.fieldPath)) {
4561
- const cursorValue = target.startAt.position[i];
4562
- if (valuesMax(segmentValue, cursorValue) === cursorValue) {
4563
- segmentValue = cursorValue;
4564
- segmentInclusive = target.startAt.inclusive;
4565
- }
4566
- break;
4567
- }
4568
- }
4569
- }
4570
- if (segmentValue === undefined) {
4534
+ const segmentBound = segment.kind === 0 /* ASCENDING */
4535
+ ? targetGetLowerBoundForField(target, segment.fieldPath, target.startAt)
4536
+ : targetGetUpperBoundForField(target, segment.fieldPath, target.startAt);
4537
+ if (!segmentBound.value) {
4571
4538
  // No lower bound exists
4572
4539
  return null;
4573
4540
  }
4574
- values.push(segmentValue);
4575
- inclusive && (inclusive = segmentInclusive);
4541
+ values.push(segmentBound.value);
4542
+ inclusive && (inclusive = segmentBound.inclusive);
4576
4543
  }
4577
4544
  return new Bound(values, inclusive);
4578
4545
  }
@@ -4587,62 +4554,125 @@ function targetGetUpperBound(target, fieldIndex) {
4587
4554
  // For each segment, retrieve an upper bound if there is a suitable filter or
4588
4555
  // endAt.
4589
4556
  for (const segment of fieldIndexGetDirectionalSegments(fieldIndex)) {
4590
- let segmentValue = undefined;
4591
- let segmentInclusive = true;
4592
- // Process all filters to find a value for the current field segment
4593
- for (const fieldFilter of targetGetFieldFiltersForPath(target, segment.fieldPath)) {
4594
- let filterValue = undefined;
4595
- let filterInclusive = true;
4596
- switch (fieldFilter.op) {
4597
- case ">=" /* GREATER_THAN_OR_EQUAL */:
4598
- case ">" /* GREATER_THAN */:
4599
- filterValue = valuesGetUpperBound(fieldFilter.value);
4600
- filterInclusive = false;
4601
- break;
4602
- case "==" /* EQUAL */:
4603
- case "in" /* IN */:
4604
- case "<=" /* LESS_THAN_OR_EQUAL */:
4605
- filterValue = fieldFilter.value;
4606
- break;
4607
- case "<" /* LESS_THAN */:
4608
- filterValue = fieldFilter.value;
4609
- filterInclusive = false;
4610
- break;
4611
- case "!=" /* NOT_EQUAL */:
4612
- case "not-in" /* NOT_IN */:
4613
- filterValue = MAX_VALUE;
4614
- break;
4615
- // Remaining filters cannot be used as upper bounds.
4616
- }
4617
- if (valuesMin(segmentValue, filterValue) === filterValue) {
4618
- segmentValue = filterValue;
4619
- segmentInclusive = filterInclusive;
4620
- }
4621
- }
4622
- // If there is a endAt bound, compare the values against the existing
4623
- // boundary to see if we can narrow the scope.
4624
- if (target.endAt !== null) {
4625
- for (let i = 0; i < target.orderBy.length; ++i) {
4626
- const orderBy = target.orderBy[i];
4627
- if (orderBy.field.isEqual(segment.fieldPath)) {
4628
- const cursorValue = target.endAt.position[i];
4629
- if (valuesMin(segmentValue, cursorValue) === cursorValue) {
4630
- segmentValue = cursorValue;
4631
- segmentInclusive = target.endAt.inclusive;
4632
- }
4633
- break;
4634
- }
4635
- }
4636
- }
4637
- if (segmentValue === undefined) {
4557
+ const segmentBound = segment.kind === 0 /* ASCENDING */
4558
+ ? targetGetUpperBoundForField(target, segment.fieldPath, target.endAt)
4559
+ : targetGetLowerBoundForField(target, segment.fieldPath, target.endAt);
4560
+ if (!segmentBound.value) {
4638
4561
  // No upper bound exists
4639
4562
  return null;
4640
4563
  }
4641
- values.push(segmentValue);
4642
- inclusive && (inclusive = segmentInclusive);
4564
+ values.push(segmentBound.value);
4565
+ inclusive && (inclusive = segmentBound.inclusive);
4643
4566
  }
4644
4567
  return new Bound(values, inclusive);
4645
4568
  }
4569
+ /**
4570
+ * Returns the value to use as the lower bound for ascending index segment at
4571
+ * the provided `fieldPath` (or the upper bound for an descending segment).
4572
+ */
4573
+ function targetGetLowerBoundForField(target, fieldPath, bound) {
4574
+ let value = undefined;
4575
+ let inclusive = true;
4576
+ // Process all filters to find a value for the current field segment
4577
+ for (const fieldFilter of targetGetFieldFiltersForPath(target, fieldPath)) {
4578
+ let filterValue = undefined;
4579
+ let filterInclusive = true;
4580
+ switch (fieldFilter.op) {
4581
+ case "<" /* LESS_THAN */:
4582
+ case "<=" /* LESS_THAN_OR_EQUAL */:
4583
+ filterValue = valuesGetLowerBound(fieldFilter.value);
4584
+ break;
4585
+ case "==" /* EQUAL */:
4586
+ case "in" /* IN */:
4587
+ case ">=" /* GREATER_THAN_OR_EQUAL */:
4588
+ filterValue = fieldFilter.value;
4589
+ break;
4590
+ case ">" /* GREATER_THAN */:
4591
+ filterValue = fieldFilter.value;
4592
+ filterInclusive = false;
4593
+ break;
4594
+ case "!=" /* NOT_EQUAL */:
4595
+ case "not-in" /* NOT_IN */:
4596
+ filterValue = MIN_VALUE;
4597
+ break;
4598
+ // Remaining filters cannot be used as lower bounds.
4599
+ }
4600
+ if (valuesMax(value, filterValue) === filterValue) {
4601
+ value = filterValue;
4602
+ inclusive = filterInclusive;
4603
+ }
4604
+ }
4605
+ // If there is an additional bound, compare the values against the existing
4606
+ // range to see if we can narrow the scope.
4607
+ if (bound !== null) {
4608
+ for (let i = 0; i < target.orderBy.length; ++i) {
4609
+ const orderBy = target.orderBy[i];
4610
+ if (orderBy.field.isEqual(fieldPath)) {
4611
+ const cursorValue = bound.position[i];
4612
+ if (valuesMax(value, cursorValue) === cursorValue) {
4613
+ value = cursorValue;
4614
+ inclusive = bound.inclusive;
4615
+ }
4616
+ break;
4617
+ }
4618
+ }
4619
+ }
4620
+ return { value, inclusive };
4621
+ }
4622
+ /**
4623
+ * Returns the value to use as the upper bound for ascending index segment at
4624
+ * the provided `fieldPath` (or the lower bound for an descending segment).
4625
+ */
4626
+ function targetGetUpperBoundForField(target, fieldPath, bound) {
4627
+ let value = undefined;
4628
+ let inclusive = true;
4629
+ // Process all filters to find a value for the current field segment
4630
+ for (const fieldFilter of targetGetFieldFiltersForPath(target, fieldPath)) {
4631
+ let filterValue = undefined;
4632
+ let filterInclusive = true;
4633
+ switch (fieldFilter.op) {
4634
+ case ">=" /* GREATER_THAN_OR_EQUAL */:
4635
+ case ">" /* GREATER_THAN */:
4636
+ filterValue = valuesGetUpperBound(fieldFilter.value);
4637
+ filterInclusive = false;
4638
+ break;
4639
+ case "==" /* EQUAL */:
4640
+ case "in" /* IN */:
4641
+ case "<=" /* LESS_THAN_OR_EQUAL */:
4642
+ filterValue = fieldFilter.value;
4643
+ break;
4644
+ case "<" /* LESS_THAN */:
4645
+ filterValue = fieldFilter.value;
4646
+ filterInclusive = false;
4647
+ break;
4648
+ case "!=" /* NOT_EQUAL */:
4649
+ case "not-in" /* NOT_IN */:
4650
+ filterValue = MAX_VALUE;
4651
+ break;
4652
+ // Remaining filters cannot be used as upper bounds.
4653
+ }
4654
+ if (valuesMin(value, filterValue) === filterValue) {
4655
+ value = filterValue;
4656
+ inclusive = filterInclusive;
4657
+ }
4658
+ }
4659
+ // If there is an additional bound, compare the values against the existing
4660
+ // range to see if we can narrow the scope.
4661
+ if (bound !== null) {
4662
+ for (let i = 0; i < target.orderBy.length; ++i) {
4663
+ const orderBy = target.orderBy[i];
4664
+ if (orderBy.field.isEqual(fieldPath)) {
4665
+ const cursorValue = bound.position[i];
4666
+ if (valuesMin(value, cursorValue) === cursorValue) {
4667
+ value = cursorValue;
4668
+ inclusive = bound.inclusive;
4669
+ }
4670
+ break;
4671
+ }
4672
+ }
4673
+ }
4674
+ return { value, inclusive };
4675
+ }
4646
4676
  class Filter {
4647
4677
  }
4648
4678
  class FieldFilter extends Filter {
@@ -10046,8 +10076,9 @@ const EMPTY_VALUE = new Uint8Array(0);
10046
10076
  * data as it supports multi-tab access.
10047
10077
  */
10048
10078
  class IndexedDbIndexManager {
10049
- constructor(user) {
10079
+ constructor(user, databaseId) {
10050
10080
  this.user = user;
10081
+ this.databaseId = databaseId;
10051
10082
  /**
10052
10083
  * An in-memory copy of the index entries we've already written since the SDK
10053
10084
  * launched. Used to avoid re-writing the same entry repeatedly.
@@ -10143,7 +10174,8 @@ class IndexedDbIndexManager {
10143
10174
  return PersistencePromise.resolve(null);
10144
10175
  }
10145
10176
  else {
10146
- let result = documentKeySet();
10177
+ let existingKeys = documentKeySet();
10178
+ const result = [];
10147
10179
  return PersistencePromise.forEach(indexes, (index, subTarget) => {
10148
10180
  logDebug(LOG_TAG$f, `Using index ${fieldIndexToString(index)} to execute ${canonifyTarget(target)}`);
10149
10181
  const arrayValues = targetGetArrayValues(subTarget, index);
@@ -10159,7 +10191,11 @@ class IndexedDbIndexManager {
10159
10191
  .loadFirst(indexRange, target.limit)
10160
10192
  .next(entries => {
10161
10193
  entries.forEach(entry => {
10162
- result = result.add(new DocumentKey(decodeResourcePath(entry.documentKey)));
10194
+ const documentKey = DocumentKey.fromSegments(entry.documentKey);
10195
+ if (!existingKeys.has(documentKey)) {
10196
+ existingKeys = existingKeys.add(documentKey);
10197
+ result.push(documentKey);
10198
+ }
10163
10199
  });
10164
10200
  });
10165
10201
  });
@@ -10258,6 +10294,15 @@ class IndexedDbIndexManager {
10258
10294
  FirestoreIndexValueWriter.INSTANCE.writeIndexValue(value, encoder.forKind(0 /* ASCENDING */));
10259
10295
  return encoder.encodedBytes();
10260
10296
  }
10297
+ /**
10298
+ * Returns an encoded form of the document key that sorts based on the key
10299
+ * ordering of the field index.
10300
+ */
10301
+ encodeDirectionalKey(fieldIndex, documentKey) {
10302
+ const encoder = new IndexByteEncoder();
10303
+ FirestoreIndexValueWriter.INSTANCE.writeIndexValue(refValue(this.databaseId, documentKey), encoder.forKind(fieldIndexGetKeyOrder(fieldIndex)));
10304
+ return encoder.encodedBytes();
10305
+ }
10261
10306
  /**
10262
10307
  * Encodes the given field values according to the specification in `target`.
10263
10308
  * For IN queries, a list of possible values is returned.
@@ -10381,7 +10426,7 @@ class IndexedDbIndexManager {
10381
10426
  return this.getExistingIndexEntries(transaction, key, fieldIndex).next(existingEntries => {
10382
10427
  const newEntries = this.computeIndexEntries(doc, fieldIndex);
10383
10428
  if (!existingEntries.isEqual(newEntries)) {
10384
- return this.updateEntries(transaction, doc, existingEntries, newEntries);
10429
+ return this.updateEntries(transaction, doc, fieldIndex, existingEntries, newEntries);
10385
10430
  }
10386
10431
  return PersistencePromise.resolve();
10387
10432
  });
@@ -10389,24 +10434,26 @@ class IndexedDbIndexManager {
10389
10434
  });
10390
10435
  });
10391
10436
  }
10392
- addIndexEntry(transaction, document, indexEntry) {
10437
+ addIndexEntry(transaction, document, fieldIndex, indexEntry) {
10393
10438
  const indexEntries = indexEntriesStore(transaction);
10394
10439
  return indexEntries.put({
10395
10440
  indexId: indexEntry.indexId,
10396
10441
  uid: this.uid,
10397
10442
  arrayValue: indexEntry.arrayValue,
10398
10443
  directionalValue: indexEntry.directionalValue,
10399
- documentKey: encodeResourcePath(document.key.path)
10444
+ orderedDocumentKey: this.encodeDirectionalKey(fieldIndex, document.key),
10445
+ documentKey: document.key.path.toArray()
10400
10446
  });
10401
10447
  }
10402
- deleteIndexEntry(transaction, document, indexEntry) {
10448
+ deleteIndexEntry(transaction, document, fieldIndex, indexEntry) {
10403
10449
  const indexEntries = indexEntriesStore(transaction);
10404
10450
  return indexEntries.delete([
10405
10451
  indexEntry.indexId,
10406
10452
  this.uid,
10407
10453
  indexEntry.arrayValue,
10408
10454
  indexEntry.directionalValue,
10409
- encodeResourcePath(document.key.path)
10455
+ this.encodeDirectionalKey(fieldIndex, document.key),
10456
+ document.key.path.toArray()
10410
10457
  ]);
10411
10458
  }
10412
10459
  getExistingIndexEntries(transaction, documentKey, fieldIndex) {
@@ -10418,7 +10465,7 @@ class IndexedDbIndexManager {
10418
10465
  range: IDBKeyRange.only([
10419
10466
  fieldIndex.indexId,
10420
10467
  this.uid,
10421
- encodeResourcePath(documentKey.path)
10468
+ this.encodeDirectionalKey(fieldIndex, documentKey)
10422
10469
  ])
10423
10470
  }, (_, entry) => {
10424
10471
  results = results.add(new IndexEntry(fieldIndex.indexId, documentKey, entry.arrayValue, entry.directionalValue));
@@ -10451,15 +10498,15 @@ class IndexedDbIndexManager {
10451
10498
  * that are no longer referenced in `newEntries` and adding all newly added
10452
10499
  * entries.
10453
10500
  */
10454
- updateEntries(transaction, document, existingEntries, newEntries) {
10501
+ updateEntries(transaction, document, fieldIndex, existingEntries, newEntries) {
10455
10502
  logDebug(LOG_TAG$f, "Updating index entries for document '%s'", document.key);
10456
10503
  const promises = [];
10457
10504
  diffSortedSets(existingEntries, newEntries, indexEntryComparator,
10458
10505
  /* onAdd= */ entry => {
10459
- promises.push(this.addIndexEntry(transaction, document, entry));
10506
+ promises.push(this.addIndexEntry(transaction, document, fieldIndex, entry));
10460
10507
  },
10461
10508
  /* onRemove= */ entry => {
10462
- promises.push(this.deleteIndexEntry(transaction, document, entry));
10509
+ promises.push(this.deleteIndexEntry(transaction, document, fieldIndex, entry));
10463
10510
  });
10464
10511
  return PersistencePromise.waitFor(promises);
10465
10512
  }
@@ -10516,13 +10563,15 @@ class IndexedDbIndexManager {
10516
10563
  this.uid,
10517
10564
  bounds[i].arrayValue,
10518
10565
  bounds[i].directionalValue,
10519
- ''
10566
+ EMPTY_VALUE,
10567
+ []
10520
10568
  ], [
10521
10569
  bounds[i + 1].indexId,
10522
10570
  this.uid,
10523
10571
  bounds[i + 1].arrayValue,
10524
10572
  bounds[i + 1].directionalValue,
10525
- ''
10573
+ EMPTY_VALUE,
10574
+ []
10526
10575
  ]));
10527
10576
  }
10528
10577
  return ranges;
@@ -12276,12 +12325,31 @@ function dbCollectionGroupKey(collectionGroup, offset) {
12276
12325
  }
12277
12326
  /**
12278
12327
  * Comparator that compares document keys according to the primary key sorting
12279
- * used by the `DbRemoteDocumentDocument` store (by collection path and then
12280
- * document ID).
12328
+ * used by the `DbRemoteDocumentDocument` store (by prefix path, collection id
12329
+ * and then document ID).
12330
+ *
12331
+ * Visible for testing.
12281
12332
  */
12282
12333
  function dbKeyComparator(l, r) {
12283
- const cmp = l.path.length - r.path.length;
12284
- return cmp !== 0 ? cmp : DocumentKey.comparator(l, r);
12334
+ const left = l.path.toArray();
12335
+ const right = r.path.toArray();
12336
+ // The ordering is based on https://chromium.googlesource.com/chromium/blink/+/fe5c21fef94dae71c1c3344775b8d8a7f7e6d9ec/Source/modules/indexeddb/IDBKey.cpp#74
12337
+ let cmp = 0;
12338
+ for (let i = 0; i < left.length - 2 && i < right.length - 2; ++i) {
12339
+ cmp = primitiveComparator(left[i], right[i]);
12340
+ if (cmp) {
12341
+ return cmp;
12342
+ }
12343
+ }
12344
+ cmp = primitiveComparator(left.length, right.length);
12345
+ if (cmp) {
12346
+ return cmp;
12347
+ }
12348
+ cmp = primitiveComparator(left[left.length - 2], right[right.length - 2]);
12349
+ if (cmp) {
12350
+ return cmp;
12351
+ }
12352
+ return primitiveComparator(left[left.length - 1], right[right.length - 1]);
12285
12353
  }
12286
12354
  /**
12287
12355
  * Schema Version for the Web client:
@@ -13182,7 +13250,7 @@ class IndexedDbPersistence {
13182
13250
  return this.remoteDocumentCache;
13183
13251
  }
13184
13252
  getIndexManager(user) {
13185
- return new IndexedDbIndexManager(user);
13253
+ return new IndexedDbIndexManager(user, this.serializer.remoteSerializer.databaseId);
13186
13254
  }
13187
13255
  getDocumentOverlayCache(user) {
13188
13256
  return IndexedDbDocumentOverlayCache.forUser(this.serializer, user);