@firebase/firestore 3.4.8-canary.7b58dabdf → 3.4.8-canary.874cdbbcc
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/firestore/lite/index.d.ts +1 -0
- package/dist/firestore/src/api/transaction.d.ts +2 -1
- package/dist/firestore/src/api/transaction_options.d.ts +17 -0
- package/dist/firestore/src/api.d.ts +1 -0
- package/dist/firestore/src/core/firestore_client.d.ts +2 -1
- package/dist/firestore/src/core/query.d.ts +2 -4
- package/dist/firestore/src/core/target.d.ts +4 -4
- package/dist/firestore/src/core/transaction_options.d.ts +25 -0
- package/dist/firestore/src/core/transaction_runner.d.ts +3 -2
- package/dist/firestore/src/lite-api/transaction.d.ts +2 -1
- package/dist/firestore/src/lite-api/transaction_options.d.ts +23 -0
- package/dist/firestore/src/local/index_manager.d.ts +5 -0
- package/dist/firestore/src/local/indexeddb_index_manager.d.ts +1 -5
- package/dist/firestore/src/local/indexeddb_schema.d.ts +1 -0
- package/dist/firestore/src/local/local_documents_view.d.ts +1 -1
- package/dist/firestore/src/local/memory_index_manager.d.ts +1 -0
- package/dist/firestore/src/local/query_engine.d.ts +44 -5
- package/dist/firestore/src/model/collections.d.ts +1 -1
- package/dist/firestore/src/model/values.d.ts +14 -2
- package/dist/firestore/src/util/misc.d.ts +3 -0
- package/dist/firestore/test/unit/local/counting_query_engine.d.ts +2 -1
- package/dist/index.d.ts +24 -1
- package/dist/index.esm2017.js +2881 -2791
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm5.js +3098 -3014
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +210 -114
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/index.node.mjs +210 -114
- package/dist/index.node.mjs.map +1 -1
- package/dist/index.rn.js +2948 -2858
- package/dist/index.rn.js.map +1 -1
- package/dist/internal.d.ts +30 -1
- package/dist/lite/firestore/lite/index.d.ts +1 -0
- package/dist/lite/firestore/src/api/transaction.d.ts +2 -1
- package/dist/lite/firestore/src/api/transaction_options.d.ts +17 -0
- package/dist/lite/firestore/src/api.d.ts +1 -0
- package/dist/lite/firestore/src/core/firestore_client.d.ts +2 -1
- package/dist/lite/firestore/src/core/query.d.ts +2 -4
- package/dist/lite/firestore/src/core/target.d.ts +4 -4
- package/dist/lite/firestore/src/core/transaction_options.d.ts +25 -0
- package/dist/lite/firestore/src/core/transaction_runner.d.ts +3 -2
- package/dist/lite/firestore/src/lite-api/transaction.d.ts +2 -1
- package/dist/lite/firestore/src/lite-api/transaction_options.d.ts +23 -0
- package/dist/lite/firestore/src/local/index_manager.d.ts +5 -0
- package/dist/lite/firestore/src/local/indexeddb_index_manager.d.ts +1 -5
- package/dist/lite/firestore/src/local/indexeddb_schema.d.ts +1 -0
- package/dist/lite/firestore/src/local/local_documents_view.d.ts +1 -1
- package/dist/lite/firestore/src/local/memory_index_manager.d.ts +1 -0
- package/dist/lite/firestore/src/local/query_engine.d.ts +44 -5
- package/dist/lite/firestore/src/model/collections.d.ts +1 -1
- package/dist/lite/firestore/src/model/values.d.ts +14 -2
- package/dist/lite/firestore/src/util/misc.d.ts +3 -0
- package/dist/lite/firestore/test/unit/local/counting_query_engine.d.ts +2 -1
- package/dist/lite/index.browser.esm2017.js +279 -250
- package/dist/lite/index.browser.esm2017.js.map +1 -1
- package/dist/lite/index.browser.esm5.js +293 -285
- package/dist/lite/index.browser.esm5.js.map +1 -1
- package/dist/lite/index.d.ts +24 -1
- package/dist/lite/index.node.cjs.js +56 -15
- package/dist/lite/index.node.cjs.js.map +1 -1
- package/dist/lite/index.node.mjs +56 -15
- package/dist/lite/index.node.mjs.map +1 -1
- package/dist/lite/index.rn.esm2017.js +1227 -1198
- package/dist/lite/index.rn.esm2017.js.map +1 -1
- package/dist/lite/internal.d.ts +25 -1
- package/dist/lite/packages/firestore/dist/lite/index.browser.esm2017.d.ts +13 -13
- package/dist/lite/packages/firestore/lite/index.d.ts +1 -0
- package/dist/lite/packages/firestore/src/api/transaction.d.ts +2 -1
- package/dist/lite/packages/firestore/src/api/transaction_options.d.ts +17 -0
- package/dist/lite/packages/firestore/src/api.d.ts +1 -0
- package/dist/lite/packages/firestore/src/core/firestore_client.d.ts +2 -1
- package/dist/lite/packages/firestore/src/core/query.d.ts +2 -4
- package/dist/lite/packages/firestore/src/core/target.d.ts +4 -4
- package/dist/lite/packages/firestore/src/core/transaction_options.d.ts +25 -0
- package/dist/lite/packages/firestore/src/core/transaction_runner.d.ts +3 -2
- package/dist/lite/packages/firestore/src/lite-api/transaction.d.ts +2 -1
- package/dist/lite/packages/firestore/src/lite-api/transaction_options.d.ts +23 -0
- package/dist/lite/packages/firestore/src/local/index_manager.d.ts +5 -0
- package/dist/lite/packages/firestore/src/local/indexeddb_index_manager.d.ts +1 -5
- package/dist/lite/packages/firestore/src/local/indexeddb_schema.d.ts +1 -0
- package/dist/lite/packages/firestore/src/local/local_documents_view.d.ts +1 -1
- package/dist/lite/packages/firestore/src/local/memory_index_manager.d.ts +1 -0
- package/dist/lite/packages/firestore/src/local/query_engine.d.ts +44 -5
- package/dist/lite/packages/firestore/src/model/collections.d.ts +1 -1
- package/dist/lite/packages/firestore/src/model/values.d.ts +14 -2
- package/dist/lite/packages/firestore/src/util/misc.d.ts +3 -0
- package/dist/lite/packages/firestore/test/unit/local/counting_query_engine.d.ts +2 -1
- package/dist/lite/private.d.ts +25 -1
- package/dist/packages/firestore/dist/index.esm2017.d.ts +157 -156
- package/dist/packages/firestore/lite/index.d.ts +1 -0
- package/dist/packages/firestore/src/api/transaction.d.ts +2 -1
- package/dist/packages/firestore/src/api/transaction_options.d.ts +17 -0
- package/dist/packages/firestore/src/api.d.ts +1 -0
- package/dist/packages/firestore/src/core/firestore_client.d.ts +2 -1
- package/dist/packages/firestore/src/core/query.d.ts +2 -4
- package/dist/packages/firestore/src/core/target.d.ts +4 -4
- package/dist/packages/firestore/src/core/transaction_options.d.ts +25 -0
- package/dist/packages/firestore/src/core/transaction_runner.d.ts +3 -2
- package/dist/packages/firestore/src/lite-api/transaction.d.ts +2 -1
- package/dist/packages/firestore/src/lite-api/transaction_options.d.ts +23 -0
- package/dist/packages/firestore/src/local/index_manager.d.ts +5 -0
- package/dist/packages/firestore/src/local/indexeddb_index_manager.d.ts +1 -5
- package/dist/packages/firestore/src/local/indexeddb_schema.d.ts +1 -0
- package/dist/packages/firestore/src/local/local_documents_view.d.ts +1 -1
- package/dist/packages/firestore/src/local/memory_index_manager.d.ts +1 -0
- package/dist/packages/firestore/src/local/query_engine.d.ts +44 -5
- package/dist/packages/firestore/src/model/collections.d.ts +1 -1
- package/dist/packages/firestore/src/model/values.d.ts +14 -2
- package/dist/packages/firestore/src/util/misc.d.ts +3 -0
- package/dist/packages/firestore/test/unit/local/counting_query_engine.d.ts +2 -1
- package/dist/private.d.ts +30 -1
- package/package.json +10 -10
package/dist/index.node.cjs.js
CHANGED
|
@@ -33,7 +33,7 @@ var grpc__namespace = /*#__PURE__*/_interopNamespace(grpc);
|
|
|
33
33
|
var protoLoader__namespace = /*#__PURE__*/_interopNamespace(protoLoader);
|
|
34
34
|
|
|
35
35
|
const name = "@firebase/firestore";
|
|
36
|
-
const version$1 = "3.4.8-canary.
|
|
36
|
+
const version$1 = "3.4.8-canary.874cdbbcc";
|
|
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.
|
|
89
|
+
const version = "9.7.0-canary.874cdbbcc";
|
|
90
90
|
|
|
91
91
|
/**
|
|
92
92
|
* @license
|
|
@@ -3346,7 +3346,7 @@ function typeOrder(value) {
|
|
|
3346
3346
|
return 4 /* ServerTimestampValue */;
|
|
3347
3347
|
}
|
|
3348
3348
|
else if (isMaxValue(value)) {
|
|
3349
|
-
return
|
|
3349
|
+
return 9007199254740991 /* MaxValue */;
|
|
3350
3350
|
}
|
|
3351
3351
|
return 10 /* ObjectValue */;
|
|
3352
3352
|
}
|
|
@@ -3558,6 +3558,15 @@ function compareArrays(left, right) {
|
|
|
3558
3558
|
return primitiveComparator(leftArray.length, rightArray.length);
|
|
3559
3559
|
}
|
|
3560
3560
|
function compareMaps(left, right) {
|
|
3561
|
+
if (left === MAX_VALUE.mapValue && right === MAX_VALUE.mapValue) {
|
|
3562
|
+
return 0;
|
|
3563
|
+
}
|
|
3564
|
+
else if (left === MAX_VALUE.mapValue) {
|
|
3565
|
+
return 1;
|
|
3566
|
+
}
|
|
3567
|
+
else if (right === MAX_VALUE.mapValue) {
|
|
3568
|
+
return -1;
|
|
3569
|
+
}
|
|
3561
3570
|
const leftMap = left.fields || {};
|
|
3562
3571
|
const leftKeys = Object.keys(leftMap);
|
|
3563
3572
|
const rightMap = right.fields || {};
|
|
@@ -3805,27 +3814,31 @@ function valuesGetUpperBound(value) {
|
|
|
3805
3814
|
return fail();
|
|
3806
3815
|
}
|
|
3807
3816
|
}
|
|
3808
|
-
function
|
|
3809
|
-
|
|
3810
|
-
|
|
3817
|
+
function lowerBoundCompare(left, right) {
|
|
3818
|
+
const cmp = valueCompare(left.value, right.value);
|
|
3819
|
+
if (cmp !== 0) {
|
|
3820
|
+
return cmp;
|
|
3811
3821
|
}
|
|
3812
|
-
|
|
3813
|
-
return
|
|
3822
|
+
if (left.inclusive && !right.inclusive) {
|
|
3823
|
+
return -1;
|
|
3814
3824
|
}
|
|
3815
|
-
else {
|
|
3816
|
-
return
|
|
3825
|
+
else if (!left.inclusive && right.inclusive) {
|
|
3826
|
+
return 1;
|
|
3817
3827
|
}
|
|
3828
|
+
return 0;
|
|
3818
3829
|
}
|
|
3819
|
-
function
|
|
3820
|
-
|
|
3821
|
-
|
|
3830
|
+
function upperBoundCompare(left, right) {
|
|
3831
|
+
const cmp = valueCompare(left.value, right.value);
|
|
3832
|
+
if (cmp !== 0) {
|
|
3833
|
+
return cmp;
|
|
3822
3834
|
}
|
|
3823
|
-
|
|
3824
|
-
return
|
|
3835
|
+
if (left.inclusive && !right.inclusive) {
|
|
3836
|
+
return 1;
|
|
3825
3837
|
}
|
|
3826
|
-
else {
|
|
3827
|
-
return
|
|
3838
|
+
else if (!left.inclusive && right.inclusive) {
|
|
3839
|
+
return -1;
|
|
3828
3840
|
}
|
|
3841
|
+
return 0;
|
|
3829
3842
|
}
|
|
3830
3843
|
|
|
3831
3844
|
/**
|
|
@@ -5209,7 +5222,7 @@ function targetGetNotInValues(target, fieldIndex) {
|
|
|
5209
5222
|
}
|
|
5210
5223
|
/**
|
|
5211
5224
|
* Returns a lower bound of field values that can be used as a starting point to
|
|
5212
|
-
* scan the index defined by `fieldIndex`. Returns `
|
|
5225
|
+
* scan the index defined by `fieldIndex`. Returns `MIN_VALUE` if no lower bound
|
|
5213
5226
|
* exists.
|
|
5214
5227
|
*/
|
|
5215
5228
|
function targetGetLowerBound(target, fieldIndex) {
|
|
@@ -5221,10 +5234,6 @@ function targetGetLowerBound(target, fieldIndex) {
|
|
|
5221
5234
|
const segmentBound = segment.kind === 0 /* ASCENDING */
|
|
5222
5235
|
? targetGetAscendingBound(target, segment.fieldPath, target.startAt)
|
|
5223
5236
|
: targetGetDescendingBound(target, segment.fieldPath, target.startAt);
|
|
5224
|
-
if (!segmentBound.value) {
|
|
5225
|
-
// No lower bound exists
|
|
5226
|
-
return null;
|
|
5227
|
-
}
|
|
5228
5237
|
values.push(segmentBound.value);
|
|
5229
5238
|
inclusive && (inclusive = segmentBound.inclusive);
|
|
5230
5239
|
}
|
|
@@ -5232,7 +5241,7 @@ function targetGetLowerBound(target, fieldIndex) {
|
|
|
5232
5241
|
}
|
|
5233
5242
|
/**
|
|
5234
5243
|
* Returns an upper bound of field values that can be used as an ending point
|
|
5235
|
-
* when scanning the index defined by `fieldIndex`. Returns `
|
|
5244
|
+
* when scanning the index defined by `fieldIndex`. Returns `MAX_VALUE` if no
|
|
5236
5245
|
* upper bound exists.
|
|
5237
5246
|
*/
|
|
5238
5247
|
function targetGetUpperBound(target, fieldIndex) {
|
|
@@ -5244,10 +5253,6 @@ function targetGetUpperBound(target, fieldIndex) {
|
|
|
5244
5253
|
const segmentBound = segment.kind === 0 /* ASCENDING */
|
|
5245
5254
|
? targetGetDescendingBound(target, segment.fieldPath, target.endAt)
|
|
5246
5255
|
: targetGetAscendingBound(target, segment.fieldPath, target.endAt);
|
|
5247
|
-
if (!segmentBound.value) {
|
|
5248
|
-
// No upper bound exists
|
|
5249
|
-
return null;
|
|
5250
|
-
}
|
|
5251
5256
|
values.push(segmentBound.value);
|
|
5252
5257
|
inclusive && (inclusive = segmentBound.inclusive);
|
|
5253
5258
|
}
|
|
@@ -5258,11 +5263,11 @@ function targetGetUpperBound(target, fieldIndex) {
|
|
|
5258
5263
|
* the provided `fieldPath` (or the upper bound for an descending segment).
|
|
5259
5264
|
*/
|
|
5260
5265
|
function targetGetAscendingBound(target, fieldPath, bound) {
|
|
5261
|
-
let value =
|
|
5266
|
+
let value = MIN_VALUE;
|
|
5262
5267
|
let inclusive = true;
|
|
5263
5268
|
// Process all filters to find a value for the current field segment
|
|
5264
5269
|
for (const fieldFilter of targetGetFieldFiltersForPath(target, fieldPath)) {
|
|
5265
|
-
let filterValue =
|
|
5270
|
+
let filterValue = MIN_VALUE;
|
|
5266
5271
|
let filterInclusive = true;
|
|
5267
5272
|
switch (fieldFilter.op) {
|
|
5268
5273
|
case "<" /* LESS_THAN */:
|
|
@@ -5284,7 +5289,7 @@ function targetGetAscendingBound(target, fieldPath, bound) {
|
|
|
5284
5289
|
break;
|
|
5285
5290
|
// Remaining filters cannot be used as lower bounds.
|
|
5286
5291
|
}
|
|
5287
|
-
if (
|
|
5292
|
+
if (lowerBoundCompare({ value, inclusive }, { value: filterValue, inclusive: filterInclusive }) < 0) {
|
|
5288
5293
|
value = filterValue;
|
|
5289
5294
|
inclusive = filterInclusive;
|
|
5290
5295
|
}
|
|
@@ -5296,7 +5301,7 @@ function targetGetAscendingBound(target, fieldPath, bound) {
|
|
|
5296
5301
|
const orderBy = target.orderBy[i];
|
|
5297
5302
|
if (orderBy.field.isEqual(fieldPath)) {
|
|
5298
5303
|
const cursorValue = bound.position[i];
|
|
5299
|
-
if (
|
|
5304
|
+
if (lowerBoundCompare({ value, inclusive }, { value: cursorValue, inclusive: bound.inclusive }) < 0) {
|
|
5300
5305
|
value = cursorValue;
|
|
5301
5306
|
inclusive = bound.inclusive;
|
|
5302
5307
|
}
|
|
@@ -5311,11 +5316,11 @@ function targetGetAscendingBound(target, fieldPath, bound) {
|
|
|
5311
5316
|
* the provided `fieldPath` (or the lower bound for a descending segment).
|
|
5312
5317
|
*/
|
|
5313
5318
|
function targetGetDescendingBound(target, fieldPath, bound) {
|
|
5314
|
-
let value =
|
|
5319
|
+
let value = MAX_VALUE;
|
|
5315
5320
|
let inclusive = true;
|
|
5316
5321
|
// Process all filters to find a value for the current field segment
|
|
5317
5322
|
for (const fieldFilter of targetGetFieldFiltersForPath(target, fieldPath)) {
|
|
5318
|
-
let filterValue =
|
|
5323
|
+
let filterValue = MAX_VALUE;
|
|
5319
5324
|
let filterInclusive = true;
|
|
5320
5325
|
switch (fieldFilter.op) {
|
|
5321
5326
|
case ">=" /* GREATER_THAN_OR_EQUAL */:
|
|
@@ -5338,7 +5343,7 @@ function targetGetDescendingBound(target, fieldPath, bound) {
|
|
|
5338
5343
|
break;
|
|
5339
5344
|
// Remaining filters cannot be used as upper bounds.
|
|
5340
5345
|
}
|
|
5341
|
-
if (
|
|
5346
|
+
if (upperBoundCompare({ value, inclusive }, { value: filterValue, inclusive: filterInclusive }) > 0) {
|
|
5342
5347
|
value = filterValue;
|
|
5343
5348
|
inclusive = filterInclusive;
|
|
5344
5349
|
}
|
|
@@ -5350,7 +5355,7 @@ function targetGetDescendingBound(target, fieldPath, bound) {
|
|
|
5350
5355
|
const orderBy = target.orderBy[i];
|
|
5351
5356
|
if (orderBy.field.isEqual(fieldPath)) {
|
|
5352
5357
|
const cursorValue = bound.position[i];
|
|
5353
|
-
if (
|
|
5358
|
+
if (upperBoundCompare({ value, inclusive }, { value: cursorValue, inclusive: bound.inclusive }) > 0) {
|
|
5354
5359
|
value = cursorValue;
|
|
5355
5360
|
inclusive = bound.inclusive;
|
|
5356
5361
|
}
|
|
@@ -5739,7 +5744,7 @@ function asCollectionQueryAtPath(query, path) {
|
|
|
5739
5744
|
* Returns true if this query does not specify any query constraints that
|
|
5740
5745
|
* could remove results.
|
|
5741
5746
|
*/
|
|
5742
|
-
function
|
|
5747
|
+
function queryMatchesAllDocuments(query) {
|
|
5743
5748
|
return (query.filters.length === 0 &&
|
|
5744
5749
|
query.limit === null &&
|
|
5745
5750
|
query.startAt == null &&
|
|
@@ -5748,12 +5753,6 @@ function matchesAllDocuments(query) {
|
|
|
5748
5753
|
(query.explicitOrderBy.length === 1 &&
|
|
5749
5754
|
query.explicitOrderBy[0].field.isKeyField())));
|
|
5750
5755
|
}
|
|
5751
|
-
function hasLimitToFirst(query) {
|
|
5752
|
-
return !isNullOrUndefined(query.limit) && query.limitType === "F" /* First */;
|
|
5753
|
-
}
|
|
5754
|
-
function hasLimitToLast(query) {
|
|
5755
|
-
return !isNullOrUndefined(query.limit) && query.limitType === "L" /* Last */;
|
|
5756
|
-
}
|
|
5757
5756
|
function getFirstOrderByField(query) {
|
|
5758
5757
|
return query.explicitOrderBy.length > 0
|
|
5759
5758
|
? query.explicitOrderBy[0].field
|
|
@@ -5863,10 +5862,10 @@ function queryToTarget(query) {
|
|
|
5863
5862
|
}
|
|
5864
5863
|
// We need to swap the cursors to match the now-flipped query ordering.
|
|
5865
5864
|
const startAt = queryImpl.endAt
|
|
5866
|
-
? new Bound(queryImpl.endAt.position,
|
|
5865
|
+
? new Bound(queryImpl.endAt.position, queryImpl.endAt.inclusive)
|
|
5867
5866
|
: null;
|
|
5868
5867
|
const endAt = queryImpl.startAt
|
|
5869
|
-
? new Bound(queryImpl.startAt.position,
|
|
5868
|
+
? new Bound(queryImpl.startAt.position, queryImpl.startAt.inclusive)
|
|
5870
5869
|
: null;
|
|
5871
5870
|
// Now return as a LimitType.First query.
|
|
5872
5871
|
queryImpl.memoizedTarget = newTarget(queryImpl.path, queryImpl.collectionGroup, orderBys, queryImpl.filters, queryImpl.limit, startAt, endAt);
|
|
@@ -6137,8 +6136,12 @@ function mutableDocumentMap() {
|
|
|
6137
6136
|
return EMPTY_MUTABLE_DOCUMENT_MAP;
|
|
6138
6137
|
}
|
|
6139
6138
|
const EMPTY_DOCUMENT_MAP = new SortedMap(DocumentKey.comparator);
|
|
6140
|
-
function documentMap() {
|
|
6141
|
-
|
|
6139
|
+
function documentMap(...docs) {
|
|
6140
|
+
let map = EMPTY_DOCUMENT_MAP;
|
|
6141
|
+
for (const doc of docs) {
|
|
6142
|
+
map = map.insert(doc.key, doc);
|
|
6143
|
+
}
|
|
6144
|
+
return map;
|
|
6142
6145
|
}
|
|
6143
6146
|
function newOverlayMap() {
|
|
6144
6147
|
return new ObjectMap(key => key.toString(), (l, r) => l.isEqual(r));
|
|
@@ -10043,6 +10046,9 @@ class MemoryIndexManager {
|
|
|
10043
10046
|
// Field indices are not supported with memory persistence.
|
|
10044
10047
|
return PersistencePromise.resolve(null);
|
|
10045
10048
|
}
|
|
10049
|
+
getMinOffset(transaction, target) {
|
|
10050
|
+
return PersistencePromise.resolve(IndexOffset.min());
|
|
10051
|
+
}
|
|
10046
10052
|
updateCollectionGroup(transaction, collectionGroup, offset) {
|
|
10047
10053
|
// Field indices are not supported with memory persistence.
|
|
10048
10054
|
return PersistencePromise.resolve();
|
|
@@ -10218,7 +10224,7 @@ class IndexedDbIndexManager {
|
|
|
10218
10224
|
const lowerBoundEncoded = this.encodeBound(index, subTarget, lowerBound);
|
|
10219
10225
|
const upperBoundEncoded = this.encodeBound(index, subTarget, upperBound);
|
|
10220
10226
|
const notInEncoded = this.encodeValues(index, subTarget, notInValues);
|
|
10221
|
-
const indexRanges = this.generateIndexRanges(index.indexId, arrayValues, lowerBoundEncoded,
|
|
10227
|
+
const indexRanges = this.generateIndexRanges(index.indexId, arrayValues, lowerBoundEncoded, lowerBound.inclusive, upperBoundEncoded, upperBound.inclusive, notInEncoded);
|
|
10222
10228
|
return PersistencePromise.forEach(indexRanges, (indexRange) => {
|
|
10223
10229
|
return indexEntries
|
|
10224
10230
|
.loadFirst(indexRange, target.limit)
|
|
@@ -10256,22 +10262,18 @@ class IndexedDbIndexManager {
|
|
|
10256
10262
|
// index range per value in an ARRAY_CONTAINS or ARRAY_CONTAINS_ANY filter
|
|
10257
10263
|
// combined with the values from the query bounds.
|
|
10258
10264
|
const totalScans = (arrayValues != null ? arrayValues.length : 1) *
|
|
10259
|
-
Math.max(lowerBounds
|
|
10265
|
+
Math.max(lowerBounds.length, upperBounds.length);
|
|
10260
10266
|
const scansPerArrayElement = totalScans / (arrayValues != null ? arrayValues.length : 1);
|
|
10261
10267
|
const indexRanges = [];
|
|
10262
10268
|
for (let i = 0; i < totalScans; ++i) {
|
|
10263
10269
|
const arrayValue = arrayValues
|
|
10264
10270
|
? this.encodeSingleElement(arrayValues[i / scansPerArrayElement])
|
|
10265
10271
|
: EMPTY_VALUE;
|
|
10266
|
-
const lowerBound = lowerBounds
|
|
10267
|
-
|
|
10268
|
-
|
|
10269
|
-
|
|
10270
|
-
|
|
10271
|
-
: this.generateEmptyBound(indexId + 1);
|
|
10272
|
-
indexRanges.push(...this.createRange(lowerBound, upperBound, notInValues.map((notIn // make non-nullable
|
|
10273
|
-
) => this.generateLowerBound(indexId, arrayValue, notIn,
|
|
10274
|
-
/* inclusive= */ true))));
|
|
10272
|
+
const lowerBound = this.generateLowerBound(indexId, arrayValue, lowerBounds[i % scansPerArrayElement], lowerBoundInclusive);
|
|
10273
|
+
const upperBound = this.generateUpperBound(indexId, arrayValue, upperBounds[i % scansPerArrayElement], upperBoundInclusive);
|
|
10274
|
+
const notInBound = notInValues.map(notIn => this.generateLowerBound(indexId, arrayValue, notIn,
|
|
10275
|
+
/* inclusive= */ true));
|
|
10276
|
+
indexRanges.push(...this.createRange(lowerBound, upperBound, notInBound));
|
|
10275
10277
|
}
|
|
10276
10278
|
return indexRanges;
|
|
10277
10279
|
}
|
|
@@ -10285,13 +10287,6 @@ class IndexedDbIndexManager {
|
|
|
10285
10287
|
const entry = new IndexEntry(indexId, DocumentKey.empty(), arrayValue, directionalValue);
|
|
10286
10288
|
return inclusive ? entry.successor() : entry;
|
|
10287
10289
|
}
|
|
10288
|
-
/**
|
|
10289
|
-
* Generates an empty bound that scopes the index scan to the current index
|
|
10290
|
-
* and user.
|
|
10291
|
-
*/
|
|
10292
|
-
generateEmptyBound(indexId) {
|
|
10293
|
-
return new IndexEntry(indexId, DocumentKey.empty(), EMPTY_VALUE, EMPTY_VALUE);
|
|
10294
|
-
}
|
|
10295
10290
|
getFieldIndex(transaction, target) {
|
|
10296
10291
|
const targetIndexMatcher = new TargetIndexMatcher(target);
|
|
10297
10292
|
const collectionGroup = target.collectionGroup != null
|
|
@@ -10311,15 +10306,18 @@ class IndexedDbIndexManager {
|
|
|
10311
10306
|
});
|
|
10312
10307
|
}
|
|
10313
10308
|
getIndexType(transaction, target) {
|
|
10314
|
-
|
|
10315
|
-
return this.
|
|
10316
|
-
|
|
10317
|
-
|
|
10318
|
-
|
|
10319
|
-
|
|
10320
|
-
|
|
10321
|
-
|
|
10322
|
-
|
|
10309
|
+
let indexType = 2 /* FULL */;
|
|
10310
|
+
return PersistencePromise.forEach(this.getSubTargets(target), (target) => {
|
|
10311
|
+
return this.getFieldIndex(transaction, target).next(index => {
|
|
10312
|
+
if (!index) {
|
|
10313
|
+
indexType = 0 /* NONE */;
|
|
10314
|
+
}
|
|
10315
|
+
else if (indexType !== 0 /* NONE */ &&
|
|
10316
|
+
index.fields.length < targetGetSegmentCount(target)) {
|
|
10317
|
+
indexType = 1 /* PARTIAL */;
|
|
10318
|
+
}
|
|
10319
|
+
});
|
|
10320
|
+
}).next(() => indexType);
|
|
10323
10321
|
}
|
|
10324
10322
|
/**
|
|
10325
10323
|
* Returns the byte encoded form of the directional values in the field index.
|
|
@@ -10383,9 +10381,6 @@ class IndexedDbIndexManager {
|
|
|
10383
10381
|
* queries, a list of possible values is returned.
|
|
10384
10382
|
*/
|
|
10385
10383
|
encodeBound(fieldIndex, target, bound) {
|
|
10386
|
-
if (bound == null) {
|
|
10387
|
-
return null;
|
|
10388
|
-
}
|
|
10389
10384
|
return this.encodeValues(fieldIndex, target, bound.position);
|
|
10390
10385
|
}
|
|
10391
10386
|
/** Returns the byte representation for the provided encoders. */
|
|
@@ -10580,7 +10575,7 @@ class IndexedDbIndexManager {
|
|
|
10580
10575
|
* '[foo > 2 && foo != 3]` becomes `[foo > 2 && < 3, foo > 3]`.
|
|
10581
10576
|
*/
|
|
10582
10577
|
createRange(lower, upper, notInValues) {
|
|
10583
|
-
// The
|
|
10578
|
+
// The notIn values need to be sorted and unique so that we can return a
|
|
10584
10579
|
// sorted set of non-overlapping ranges.
|
|
10585
10580
|
notInValues = notInValues
|
|
10586
10581
|
.sort((l, r) => indexEntryComparator(l, r))
|
|
@@ -10626,6 +10621,20 @@ class IndexedDbIndexManager {
|
|
|
10626
10621
|
}
|
|
10627
10622
|
return ranges;
|
|
10628
10623
|
}
|
|
10624
|
+
getMinOffset(transaction, target) {
|
|
10625
|
+
let offset;
|
|
10626
|
+
return PersistencePromise.forEach(this.getSubTargets(target), (target) => {
|
|
10627
|
+
return this.getFieldIndex(transaction, target).next(index => {
|
|
10628
|
+
if (!index) {
|
|
10629
|
+
offset = IndexOffset.min();
|
|
10630
|
+
}
|
|
10631
|
+
else if (!offset ||
|
|
10632
|
+
indexOffsetComparator(index.indexState.offset, offset) < 0) {
|
|
10633
|
+
offset = index.indexState.offset;
|
|
10634
|
+
}
|
|
10635
|
+
});
|
|
10636
|
+
}).next(() => offset);
|
|
10637
|
+
}
|
|
10629
10638
|
}
|
|
10630
10639
|
/**
|
|
10631
10640
|
* Helper to get a typed SimpleDbStore for the collectionParents
|
|
@@ -13796,7 +13805,7 @@ class LocalStoreImpl {
|
|
|
13796
13805
|
this.mutationQueue = this.persistence.getMutationQueue(user, this.indexManager);
|
|
13797
13806
|
this.localDocuments = new LocalDocumentsView(this.remoteDocuments, this.mutationQueue, this.indexManager);
|
|
13798
13807
|
this.remoteDocuments.setIndexManager(this.indexManager);
|
|
13799
|
-
this.queryEngine.
|
|
13808
|
+
this.queryEngine.initialize(this.localDocuments, this.indexManager);
|
|
13800
13809
|
}
|
|
13801
13810
|
collectGarbage(garbageCollector) {
|
|
13802
13811
|
return this.persistence.runTransaction('Collect garbage', 'readwrite-primary', txn => garbageCollector.collect(txn, this.targetDataByTarget));
|
|
@@ -15538,10 +15547,30 @@ class MemoryEagerDelegate {
|
|
|
15538
15547
|
* limitations under the License.
|
|
15539
15548
|
*/
|
|
15540
15549
|
/**
|
|
15541
|
-
*
|
|
15542
|
-
*
|
|
15543
|
-
*
|
|
15544
|
-
*
|
|
15550
|
+
* The Firestore query engine.
|
|
15551
|
+
*
|
|
15552
|
+
* Firestore queries can be executed in three modes. The Query Engine determines
|
|
15553
|
+
* what mode to use based on what data is persisted. The mode only determines
|
|
15554
|
+
* the runtime complexity of the query - the result set is equivalent across all
|
|
15555
|
+
* implementations.
|
|
15556
|
+
*
|
|
15557
|
+
* The Query engine will use indexed-based execution if a user has configured
|
|
15558
|
+
* any index that can be used to execute query (via `setIndexConfiguration()`).
|
|
15559
|
+
* Otherwise, the engine will try to optimize the query by re-using a previously
|
|
15560
|
+
* persisted query result. If that is not possible, the query will be executed
|
|
15561
|
+
* via a full collection scan.
|
|
15562
|
+
*
|
|
15563
|
+
* Index-based execution is the default when available. The query engine
|
|
15564
|
+
* supports partial indexed execution and merges the result from the index
|
|
15565
|
+
* lookup with documents that have not yet been indexed. The index evaluation
|
|
15566
|
+
* matches the backend's format and as such, the SDK can use indexing for all
|
|
15567
|
+
* queries that the backend supports.
|
|
15568
|
+
*
|
|
15569
|
+
* If no index exists, the query engine tries to take advantage of the target
|
|
15570
|
+
* document mapping in the TargetCache. These mappings exists for all queries
|
|
15571
|
+
* that have been synced with the backend at least once and allow the query
|
|
15572
|
+
* engine to only read documents that previously matched a query plus any
|
|
15573
|
+
* documents that were edited after the query was last listened to.
|
|
15545
15574
|
*
|
|
15546
15575
|
* There are some cases when this optimization is not guaranteed to produce
|
|
15547
15576
|
* the same results as full collection scans. In these cases, query
|
|
@@ -15556,16 +15585,41 @@ class MemoryEagerDelegate {
|
|
|
15556
15585
|
* - Queries that have never been CURRENT or free of limbo documents.
|
|
15557
15586
|
*/
|
|
15558
15587
|
class QueryEngine {
|
|
15588
|
+
constructor() {
|
|
15589
|
+
this.initialized = false;
|
|
15590
|
+
}
|
|
15559
15591
|
/** Sets the document view to query against. */
|
|
15560
|
-
|
|
15592
|
+
initialize(localDocuments, indexManager) {
|
|
15561
15593
|
this.localDocumentsView = localDocuments;
|
|
15594
|
+
this.indexManager = indexManager;
|
|
15595
|
+
this.initialized = true;
|
|
15562
15596
|
}
|
|
15563
15597
|
/** Returns all local documents matching the specified query. */
|
|
15564
15598
|
getDocumentsMatchingQuery(transaction, query, lastLimboFreeSnapshotVersion, remoteKeys) {
|
|
15565
|
-
|
|
15566
|
-
|
|
15567
|
-
|
|
15568
|
-
|
|
15599
|
+
return this.performQueryUsingIndex(transaction, query)
|
|
15600
|
+
.next(result => result
|
|
15601
|
+
? result
|
|
15602
|
+
: this.performQueryUsingRemoteKeys(transaction, query, remoteKeys, lastLimboFreeSnapshotVersion))
|
|
15603
|
+
.next(result => result ? result : this.executeFullCollectionScan(transaction, query));
|
|
15604
|
+
}
|
|
15605
|
+
/**
|
|
15606
|
+
* Performs an indexed query that evaluates the query based on a collection's
|
|
15607
|
+
* persisted index values. Returns `null` if an index is not available.
|
|
15608
|
+
*/
|
|
15609
|
+
performQueryUsingIndex(transaction, query) {
|
|
15610
|
+
{
|
|
15611
|
+
return PersistencePromise.resolve(null);
|
|
15612
|
+
}
|
|
15613
|
+
}
|
|
15614
|
+
/**
|
|
15615
|
+
* Performs a query based on the target's persisted query mapping. Returns
|
|
15616
|
+
* `null` if the mapping is not available or cannot be used.
|
|
15617
|
+
*/
|
|
15618
|
+
performQueryUsingRemoteKeys(transaction, query, remoteKeys, lastLimboFreeSnapshotVersion) {
|
|
15619
|
+
if (queryMatchesAllDocuments(query)) {
|
|
15620
|
+
// Queries that match all documents don't benefit from using
|
|
15621
|
+
// key-based lookups. It is more efficient to scan all documents in a
|
|
15622
|
+
// collection, rather than to perform individual lookups.
|
|
15569
15623
|
return this.executeFullCollectionScan(transaction, query);
|
|
15570
15624
|
}
|
|
15571
15625
|
// Queries that have never seen a snapshot without limbo free documents
|
|
@@ -15575,8 +15629,7 @@ class QueryEngine {
|
|
|
15575
15629
|
}
|
|
15576
15630
|
return this.localDocumentsView.getDocuments(transaction, remoteKeys).next(documents => {
|
|
15577
15631
|
const previousResults = this.applyQuery(query, documents);
|
|
15578
|
-
if ((
|
|
15579
|
-
this.needsRefill(query.limitType, previousResults, remoteKeys, lastLimboFreeSnapshotVersion)) {
|
|
15632
|
+
if (this.needsRefill(query, previousResults, remoteKeys, lastLimboFreeSnapshotVersion)) {
|
|
15580
15633
|
return this.executeFullCollectionScan(transaction, query);
|
|
15581
15634
|
}
|
|
15582
15635
|
if (getLogLevel() <= logger.LogLevel.DEBUG) {
|
|
@@ -15584,15 +15637,7 @@ class QueryEngine {
|
|
|
15584
15637
|
}
|
|
15585
15638
|
// Retrieve all results for documents that were updated since the last
|
|
15586
15639
|
// limbo-document free remote snapshot.
|
|
15587
|
-
return this.
|
|
15588
|
-
// We merge `previousResults` into `updateResults`, since
|
|
15589
|
-
// `updateResults` is already a DocumentMap. If a document is
|
|
15590
|
-
// contained in both lists, then its contents are the same.
|
|
15591
|
-
previousResults.forEach(doc => {
|
|
15592
|
-
updatedResults = updatedResults.insert(doc.key, doc);
|
|
15593
|
-
});
|
|
15594
|
-
return updatedResults;
|
|
15595
|
-
});
|
|
15640
|
+
return this.appendRemainingResults(transaction, previousResults, query, newIndexOffsetSuccessorFromReadTime(lastLimboFreeSnapshotVersion, INITIAL_LARGEST_BATCH_ID));
|
|
15596
15641
|
});
|
|
15597
15642
|
}
|
|
15598
15643
|
/** Applies the query filter and sorting to the provided documents. */
|
|
@@ -15611,6 +15656,7 @@ class QueryEngine {
|
|
|
15611
15656
|
* Determines if a limit query needs to be refilled from cache, making it
|
|
15612
15657
|
* ineligible for index-free execution.
|
|
15613
15658
|
*
|
|
15659
|
+
* @param query The query.
|
|
15614
15660
|
* @param sortedPreviousResults - The documents that matched the query when it
|
|
15615
15661
|
* was last synchronized, sorted by the query's comparator.
|
|
15616
15662
|
* @param remoteKeys - The document keys that matched the query at the last
|
|
@@ -15618,10 +15664,14 @@ class QueryEngine {
|
|
|
15618
15664
|
* @param limboFreeSnapshotVersion - The version of the snapshot when the
|
|
15619
15665
|
* query was last synchronized.
|
|
15620
15666
|
*/
|
|
15621
|
-
needsRefill(
|
|
15622
|
-
|
|
15623
|
-
|
|
15667
|
+
needsRefill(query, sortedPreviousResults, remoteKeys, limboFreeSnapshotVersion) {
|
|
15668
|
+
if (query.limit === null) {
|
|
15669
|
+
// Queries without limits do not need to be refilled.
|
|
15670
|
+
return false;
|
|
15671
|
+
}
|
|
15624
15672
|
if (remoteKeys.size !== sortedPreviousResults.size) {
|
|
15673
|
+
// The query needs to be refilled if a previously matching document no
|
|
15674
|
+
// longer matches.
|
|
15625
15675
|
return true;
|
|
15626
15676
|
}
|
|
15627
15677
|
// Limit queries are not eligible for index-free query execution if there is
|
|
@@ -15632,7 +15682,7 @@ class QueryEngine {
|
|
|
15632
15682
|
// the boundary of the limit itself did not change and documents from cache
|
|
15633
15683
|
// will continue to be "rejected" by this boundary. Therefore, we can ignore
|
|
15634
15684
|
// any modifications that don't affect the last document.
|
|
15635
|
-
const docAtLimitEdge = limitType === "F" /* First */
|
|
15685
|
+
const docAtLimitEdge = query.limitType === "F" /* First */
|
|
15636
15686
|
? sortedPreviousResults.last()
|
|
15637
15687
|
: sortedPreviousResults.first();
|
|
15638
15688
|
if (!docAtLimitEdge) {
|
|
@@ -15648,6 +15698,22 @@ class QueryEngine {
|
|
|
15648
15698
|
}
|
|
15649
15699
|
return this.localDocumentsView.getDocumentsMatchingQuery(transaction, query, IndexOffset.min());
|
|
15650
15700
|
}
|
|
15701
|
+
/**
|
|
15702
|
+
* Combines the results from an indexed execution with the remaining documents
|
|
15703
|
+
* that have not yet been indexed.
|
|
15704
|
+
*/
|
|
15705
|
+
appendRemainingResults(transaction, indexedResults, query, offset) {
|
|
15706
|
+
// Retrieve all results for documents that were updated since the offset.
|
|
15707
|
+
return this.localDocumentsView
|
|
15708
|
+
.getDocumentsMatchingQuery(transaction, query, offset)
|
|
15709
|
+
.next(remainingResults => {
|
|
15710
|
+
// Merge with existing results
|
|
15711
|
+
indexedResults.forEach(d => {
|
|
15712
|
+
remainingResults = remainingResults.insert(d.key, d);
|
|
15713
|
+
});
|
|
15714
|
+
return remainingResults;
|
|
15715
|
+
});
|
|
15716
|
+
}
|
|
15651
15717
|
}
|
|
15652
15718
|
|
|
15653
15719
|
/**
|
|
@@ -21907,10 +21973,12 @@ class View {
|
|
|
21907
21973
|
//
|
|
21908
21974
|
// Note that this should never get used in a refill (when previousChanges is
|
|
21909
21975
|
// set), because there will only be adds -- no deletes or updates.
|
|
21910
|
-
const lastDocInLimit =
|
|
21976
|
+
const lastDocInLimit = this.query.limitType === "F" /* First */ &&
|
|
21977
|
+
oldDocumentSet.size === this.query.limit
|
|
21911
21978
|
? oldDocumentSet.last()
|
|
21912
21979
|
: null;
|
|
21913
|
-
const firstDocInLimit =
|
|
21980
|
+
const firstDocInLimit = this.query.limitType === "L" /* Last */ &&
|
|
21981
|
+
oldDocumentSet.size === this.query.limit
|
|
21914
21982
|
? oldDocumentSet.first()
|
|
21915
21983
|
: null;
|
|
21916
21984
|
docChanges.inorderTraversal((key, entry) => {
|
|
@@ -21983,9 +22051,9 @@ class View {
|
|
|
21983
22051
|
}
|
|
21984
22052
|
});
|
|
21985
22053
|
// Drop documents out to meet limit/limitToLast requirement.
|
|
21986
|
-
if (
|
|
22054
|
+
if (this.query.limit !== null) {
|
|
21987
22055
|
while (newDocumentSet.size > this.query.limit) {
|
|
21988
|
-
const oldDoc =
|
|
22056
|
+
const oldDoc = this.query.limitType === "F" /* First */
|
|
21989
22057
|
? newDocumentSet.last()
|
|
21990
22058
|
: newDocumentSet.first();
|
|
21991
22059
|
newDocumentSet = newDocumentSet.delete(oldDoc.key);
|
|
@@ -23986,18 +24054,18 @@ class Transaction$2 {
|
|
|
23986
24054
|
* See the License for the specific language governing permissions and
|
|
23987
24055
|
* limitations under the License.
|
|
23988
24056
|
*/
|
|
23989
|
-
const DEFAULT_MAX_ATTEMPTS_COUNT = 5;
|
|
23990
24057
|
/**
|
|
23991
24058
|
* TransactionRunner encapsulates the logic needed to run and retry transactions
|
|
23992
24059
|
* with backoff.
|
|
23993
24060
|
*/
|
|
23994
24061
|
class TransactionRunner {
|
|
23995
|
-
constructor(asyncQueue, datastore, updateFunction, deferred) {
|
|
24062
|
+
constructor(asyncQueue, datastore, options, updateFunction, deferred) {
|
|
23996
24063
|
this.asyncQueue = asyncQueue;
|
|
23997
24064
|
this.datastore = datastore;
|
|
24065
|
+
this.options = options;
|
|
23998
24066
|
this.updateFunction = updateFunction;
|
|
23999
24067
|
this.deferred = deferred;
|
|
24000
|
-
this.attemptsRemaining =
|
|
24068
|
+
this.attemptsRemaining = options.maxAttempts;
|
|
24001
24069
|
this.backoff = new ExponentialBackoff(this.asyncQueue, "transaction_retry" /* TransactionRetry */);
|
|
24002
24070
|
}
|
|
24003
24071
|
/** Runs the transaction and sets the result on deferred. */
|
|
@@ -24355,11 +24423,11 @@ function firestoreClientAddSnapshotsInSyncListener(client, observer) {
|
|
|
24355
24423
|
* been committed. For this reason, it is required that all reads are
|
|
24356
24424
|
* performed before any writes. Transactions must be performed while online.
|
|
24357
24425
|
*/
|
|
24358
|
-
function firestoreClientTransaction(client, updateFunction) {
|
|
24426
|
+
function firestoreClientTransaction(client, updateFunction, options) {
|
|
24359
24427
|
const deferred = new Deferred();
|
|
24360
24428
|
client.asyncQueue.enqueueAndForget(async () => {
|
|
24361
24429
|
const datastore = await getDatastore(client);
|
|
24362
|
-
new TransactionRunner(client.asyncQueue, datastore, updateFunction, deferred).run();
|
|
24430
|
+
new TransactionRunner(client.asyncQueue, datastore, options, updateFunction, deferred).run();
|
|
24363
24431
|
});
|
|
24364
24432
|
return deferred.promise;
|
|
24365
24433
|
}
|
|
@@ -27116,7 +27184,8 @@ function snapshotEqual(left, right) {
|
|
|
27116
27184
|
* limitations under the License.
|
|
27117
27185
|
*/
|
|
27118
27186
|
function validateHasExplicitOrderByForLimitToLast(query) {
|
|
27119
|
-
if (
|
|
27187
|
+
if (query.limitType === "L" /* Last */ &&
|
|
27188
|
+
query.explicitOrderBy.length === 0) {
|
|
27120
27189
|
throw new FirestoreError(Code.UNIMPLEMENTED, 'limitToLast() queries require specifying at least one orderBy() clause');
|
|
27121
27190
|
}
|
|
27122
27191
|
}
|
|
@@ -27558,6 +27627,31 @@ function validateOrderByAndInequalityMatch(baseQuery, inequality, orderBy) {
|
|
|
27558
27627
|
}
|
|
27559
27628
|
}
|
|
27560
27629
|
|
|
27630
|
+
/**
|
|
27631
|
+
* @license
|
|
27632
|
+
* Copyright 2022 Google LLC
|
|
27633
|
+
*
|
|
27634
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
27635
|
+
* you may not use this file except in compliance with the License.
|
|
27636
|
+
* You may obtain a copy of the License at
|
|
27637
|
+
*
|
|
27638
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
27639
|
+
*
|
|
27640
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
27641
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
27642
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
27643
|
+
* See the License for the specific language governing permissions and
|
|
27644
|
+
* limitations under the License.
|
|
27645
|
+
*/
|
|
27646
|
+
const DEFAULT_TRANSACTION_OPTIONS = {
|
|
27647
|
+
maxAttempts: 5
|
|
27648
|
+
};
|
|
27649
|
+
function validateTransactionOptions(options) {
|
|
27650
|
+
if (options.maxAttempts < 1) {
|
|
27651
|
+
throw new FirestoreError(Code.INVALID_ARGUMENT, 'Max attempts must be at least 1');
|
|
27652
|
+
}
|
|
27653
|
+
}
|
|
27654
|
+
|
|
27561
27655
|
/**
|
|
27562
27656
|
* @license
|
|
27563
27657
|
* Copyright 2020 Google LLC
|
|
@@ -28279,10 +28373,12 @@ class Transaction extends Transaction$1 {
|
|
|
28279
28373
|
* `updateFunction `is returned here. Otherwise, if the transaction failed, a
|
|
28280
28374
|
* rejected promise with the corresponding failure error is returned.
|
|
28281
28375
|
*/
|
|
28282
|
-
function runTransaction(firestore, updateFunction) {
|
|
28376
|
+
function runTransaction(firestore, updateFunction, options) {
|
|
28283
28377
|
firestore = cast(firestore, Firestore);
|
|
28378
|
+
const optionsWithDefaults = Object.assign(Object.assign({}, DEFAULT_TRANSACTION_OPTIONS), options);
|
|
28379
|
+
validateTransactionOptions(optionsWithDefaults);
|
|
28284
28380
|
const client = ensureFirestoreConfigured(firestore);
|
|
28285
|
-
return firestoreClientTransaction(client, internalTransaction => updateFunction(new Transaction(firestore, internalTransaction)));
|
|
28381
|
+
return firestoreClientTransaction(client, internalTransaction => updateFunction(new Transaction(firestore, internalTransaction)), optionsWithDefaults);
|
|
28286
28382
|
}
|
|
28287
28383
|
|
|
28288
28384
|
/**
|