@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.mjs
CHANGED
|
@@ -8,7 +8,7 @@ import * as grpc from '@grpc/grpc-js';
|
|
|
8
8
|
import * as protoLoader from '@grpc/proto-loader';
|
|
9
9
|
|
|
10
10
|
const name = "@firebase/firestore";
|
|
11
|
-
const version$1 = "3.4.8-canary.
|
|
11
|
+
const version$1 = "3.4.8-canary.874cdbbcc";
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* @license
|
|
@@ -61,7 +61,7 @@ User.GOOGLE_CREDENTIALS = new User('google-credentials-uid');
|
|
|
61
61
|
User.FIRST_PARTY = new User('first-party-uid');
|
|
62
62
|
User.MOCK_USER = new User('mock-user');
|
|
63
63
|
|
|
64
|
-
const version = "9.
|
|
64
|
+
const version = "9.7.0-canary.874cdbbcc";
|
|
65
65
|
|
|
66
66
|
/**
|
|
67
67
|
* @license
|
|
@@ -3321,7 +3321,7 @@ function typeOrder(value) {
|
|
|
3321
3321
|
return 4 /* ServerTimestampValue */;
|
|
3322
3322
|
}
|
|
3323
3323
|
else if (isMaxValue(value)) {
|
|
3324
|
-
return
|
|
3324
|
+
return 9007199254740991 /* MaxValue */;
|
|
3325
3325
|
}
|
|
3326
3326
|
return 10 /* ObjectValue */;
|
|
3327
3327
|
}
|
|
@@ -3533,6 +3533,15 @@ function compareArrays(left, right) {
|
|
|
3533
3533
|
return primitiveComparator(leftArray.length, rightArray.length);
|
|
3534
3534
|
}
|
|
3535
3535
|
function compareMaps(left, right) {
|
|
3536
|
+
if (left === MAX_VALUE.mapValue && right === MAX_VALUE.mapValue) {
|
|
3537
|
+
return 0;
|
|
3538
|
+
}
|
|
3539
|
+
else if (left === MAX_VALUE.mapValue) {
|
|
3540
|
+
return 1;
|
|
3541
|
+
}
|
|
3542
|
+
else if (right === MAX_VALUE.mapValue) {
|
|
3543
|
+
return -1;
|
|
3544
|
+
}
|
|
3536
3545
|
const leftMap = left.fields || {};
|
|
3537
3546
|
const leftKeys = Object.keys(leftMap);
|
|
3538
3547
|
const rightMap = right.fields || {};
|
|
@@ -3780,27 +3789,31 @@ function valuesGetUpperBound(value) {
|
|
|
3780
3789
|
return fail();
|
|
3781
3790
|
}
|
|
3782
3791
|
}
|
|
3783
|
-
function
|
|
3784
|
-
|
|
3785
|
-
|
|
3792
|
+
function lowerBoundCompare(left, right) {
|
|
3793
|
+
const cmp = valueCompare(left.value, right.value);
|
|
3794
|
+
if (cmp !== 0) {
|
|
3795
|
+
return cmp;
|
|
3786
3796
|
}
|
|
3787
|
-
|
|
3788
|
-
return
|
|
3797
|
+
if (left.inclusive && !right.inclusive) {
|
|
3798
|
+
return -1;
|
|
3789
3799
|
}
|
|
3790
|
-
else {
|
|
3791
|
-
return
|
|
3800
|
+
else if (!left.inclusive && right.inclusive) {
|
|
3801
|
+
return 1;
|
|
3792
3802
|
}
|
|
3803
|
+
return 0;
|
|
3793
3804
|
}
|
|
3794
|
-
function
|
|
3795
|
-
|
|
3796
|
-
|
|
3805
|
+
function upperBoundCompare(left, right) {
|
|
3806
|
+
const cmp = valueCompare(left.value, right.value);
|
|
3807
|
+
if (cmp !== 0) {
|
|
3808
|
+
return cmp;
|
|
3797
3809
|
}
|
|
3798
|
-
|
|
3799
|
-
return
|
|
3810
|
+
if (left.inclusive && !right.inclusive) {
|
|
3811
|
+
return 1;
|
|
3800
3812
|
}
|
|
3801
|
-
else {
|
|
3802
|
-
return
|
|
3813
|
+
else if (!left.inclusive && right.inclusive) {
|
|
3814
|
+
return -1;
|
|
3803
3815
|
}
|
|
3816
|
+
return 0;
|
|
3804
3817
|
}
|
|
3805
3818
|
|
|
3806
3819
|
/**
|
|
@@ -5184,7 +5197,7 @@ function targetGetNotInValues(target, fieldIndex) {
|
|
|
5184
5197
|
}
|
|
5185
5198
|
/**
|
|
5186
5199
|
* Returns a lower bound of field values that can be used as a starting point to
|
|
5187
|
-
* scan the index defined by `fieldIndex`. Returns `
|
|
5200
|
+
* scan the index defined by `fieldIndex`. Returns `MIN_VALUE` if no lower bound
|
|
5188
5201
|
* exists.
|
|
5189
5202
|
*/
|
|
5190
5203
|
function targetGetLowerBound(target, fieldIndex) {
|
|
@@ -5196,10 +5209,6 @@ function targetGetLowerBound(target, fieldIndex) {
|
|
|
5196
5209
|
const segmentBound = segment.kind === 0 /* ASCENDING */
|
|
5197
5210
|
? targetGetAscendingBound(target, segment.fieldPath, target.startAt)
|
|
5198
5211
|
: targetGetDescendingBound(target, segment.fieldPath, target.startAt);
|
|
5199
|
-
if (!segmentBound.value) {
|
|
5200
|
-
// No lower bound exists
|
|
5201
|
-
return null;
|
|
5202
|
-
}
|
|
5203
5212
|
values.push(segmentBound.value);
|
|
5204
5213
|
inclusive && (inclusive = segmentBound.inclusive);
|
|
5205
5214
|
}
|
|
@@ -5207,7 +5216,7 @@ function targetGetLowerBound(target, fieldIndex) {
|
|
|
5207
5216
|
}
|
|
5208
5217
|
/**
|
|
5209
5218
|
* Returns an upper bound of field values that can be used as an ending point
|
|
5210
|
-
* when scanning the index defined by `fieldIndex`. Returns `
|
|
5219
|
+
* when scanning the index defined by `fieldIndex`. Returns `MAX_VALUE` if no
|
|
5211
5220
|
* upper bound exists.
|
|
5212
5221
|
*/
|
|
5213
5222
|
function targetGetUpperBound(target, fieldIndex) {
|
|
@@ -5219,10 +5228,6 @@ function targetGetUpperBound(target, fieldIndex) {
|
|
|
5219
5228
|
const segmentBound = segment.kind === 0 /* ASCENDING */
|
|
5220
5229
|
? targetGetDescendingBound(target, segment.fieldPath, target.endAt)
|
|
5221
5230
|
: targetGetAscendingBound(target, segment.fieldPath, target.endAt);
|
|
5222
|
-
if (!segmentBound.value) {
|
|
5223
|
-
// No upper bound exists
|
|
5224
|
-
return null;
|
|
5225
|
-
}
|
|
5226
5231
|
values.push(segmentBound.value);
|
|
5227
5232
|
inclusive && (inclusive = segmentBound.inclusive);
|
|
5228
5233
|
}
|
|
@@ -5233,11 +5238,11 @@ function targetGetUpperBound(target, fieldIndex) {
|
|
|
5233
5238
|
* the provided `fieldPath` (or the upper bound for an descending segment).
|
|
5234
5239
|
*/
|
|
5235
5240
|
function targetGetAscendingBound(target, fieldPath, bound) {
|
|
5236
|
-
let value =
|
|
5241
|
+
let value = MIN_VALUE;
|
|
5237
5242
|
let inclusive = true;
|
|
5238
5243
|
// Process all filters to find a value for the current field segment
|
|
5239
5244
|
for (const fieldFilter of targetGetFieldFiltersForPath(target, fieldPath)) {
|
|
5240
|
-
let filterValue =
|
|
5245
|
+
let filterValue = MIN_VALUE;
|
|
5241
5246
|
let filterInclusive = true;
|
|
5242
5247
|
switch (fieldFilter.op) {
|
|
5243
5248
|
case "<" /* LESS_THAN */:
|
|
@@ -5259,7 +5264,7 @@ function targetGetAscendingBound(target, fieldPath, bound) {
|
|
|
5259
5264
|
break;
|
|
5260
5265
|
// Remaining filters cannot be used as lower bounds.
|
|
5261
5266
|
}
|
|
5262
|
-
if (
|
|
5267
|
+
if (lowerBoundCompare({ value, inclusive }, { value: filterValue, inclusive: filterInclusive }) < 0) {
|
|
5263
5268
|
value = filterValue;
|
|
5264
5269
|
inclusive = filterInclusive;
|
|
5265
5270
|
}
|
|
@@ -5271,7 +5276,7 @@ function targetGetAscendingBound(target, fieldPath, bound) {
|
|
|
5271
5276
|
const orderBy = target.orderBy[i];
|
|
5272
5277
|
if (orderBy.field.isEqual(fieldPath)) {
|
|
5273
5278
|
const cursorValue = bound.position[i];
|
|
5274
|
-
if (
|
|
5279
|
+
if (lowerBoundCompare({ value, inclusive }, { value: cursorValue, inclusive: bound.inclusive }) < 0) {
|
|
5275
5280
|
value = cursorValue;
|
|
5276
5281
|
inclusive = bound.inclusive;
|
|
5277
5282
|
}
|
|
@@ -5286,11 +5291,11 @@ function targetGetAscendingBound(target, fieldPath, bound) {
|
|
|
5286
5291
|
* the provided `fieldPath` (or the lower bound for a descending segment).
|
|
5287
5292
|
*/
|
|
5288
5293
|
function targetGetDescendingBound(target, fieldPath, bound) {
|
|
5289
|
-
let value =
|
|
5294
|
+
let value = MAX_VALUE;
|
|
5290
5295
|
let inclusive = true;
|
|
5291
5296
|
// Process all filters to find a value for the current field segment
|
|
5292
5297
|
for (const fieldFilter of targetGetFieldFiltersForPath(target, fieldPath)) {
|
|
5293
|
-
let filterValue =
|
|
5298
|
+
let filterValue = MAX_VALUE;
|
|
5294
5299
|
let filterInclusive = true;
|
|
5295
5300
|
switch (fieldFilter.op) {
|
|
5296
5301
|
case ">=" /* GREATER_THAN_OR_EQUAL */:
|
|
@@ -5313,7 +5318,7 @@ function targetGetDescendingBound(target, fieldPath, bound) {
|
|
|
5313
5318
|
break;
|
|
5314
5319
|
// Remaining filters cannot be used as upper bounds.
|
|
5315
5320
|
}
|
|
5316
|
-
if (
|
|
5321
|
+
if (upperBoundCompare({ value, inclusive }, { value: filterValue, inclusive: filterInclusive }) > 0) {
|
|
5317
5322
|
value = filterValue;
|
|
5318
5323
|
inclusive = filterInclusive;
|
|
5319
5324
|
}
|
|
@@ -5325,7 +5330,7 @@ function targetGetDescendingBound(target, fieldPath, bound) {
|
|
|
5325
5330
|
const orderBy = target.orderBy[i];
|
|
5326
5331
|
if (orderBy.field.isEqual(fieldPath)) {
|
|
5327
5332
|
const cursorValue = bound.position[i];
|
|
5328
|
-
if (
|
|
5333
|
+
if (upperBoundCompare({ value, inclusive }, { value: cursorValue, inclusive: bound.inclusive }) > 0) {
|
|
5329
5334
|
value = cursorValue;
|
|
5330
5335
|
inclusive = bound.inclusive;
|
|
5331
5336
|
}
|
|
@@ -5714,7 +5719,7 @@ function asCollectionQueryAtPath(query, path) {
|
|
|
5714
5719
|
* Returns true if this query does not specify any query constraints that
|
|
5715
5720
|
* could remove results.
|
|
5716
5721
|
*/
|
|
5717
|
-
function
|
|
5722
|
+
function queryMatchesAllDocuments(query) {
|
|
5718
5723
|
return (query.filters.length === 0 &&
|
|
5719
5724
|
query.limit === null &&
|
|
5720
5725
|
query.startAt == null &&
|
|
@@ -5723,12 +5728,6 @@ function matchesAllDocuments(query) {
|
|
|
5723
5728
|
(query.explicitOrderBy.length === 1 &&
|
|
5724
5729
|
query.explicitOrderBy[0].field.isKeyField())));
|
|
5725
5730
|
}
|
|
5726
|
-
function hasLimitToFirst(query) {
|
|
5727
|
-
return !isNullOrUndefined(query.limit) && query.limitType === "F" /* First */;
|
|
5728
|
-
}
|
|
5729
|
-
function hasLimitToLast(query) {
|
|
5730
|
-
return !isNullOrUndefined(query.limit) && query.limitType === "L" /* Last */;
|
|
5731
|
-
}
|
|
5732
5731
|
function getFirstOrderByField(query) {
|
|
5733
5732
|
return query.explicitOrderBy.length > 0
|
|
5734
5733
|
? query.explicitOrderBy[0].field
|
|
@@ -5838,10 +5837,10 @@ function queryToTarget(query) {
|
|
|
5838
5837
|
}
|
|
5839
5838
|
// We need to swap the cursors to match the now-flipped query ordering.
|
|
5840
5839
|
const startAt = queryImpl.endAt
|
|
5841
|
-
? new Bound(queryImpl.endAt.position,
|
|
5840
|
+
? new Bound(queryImpl.endAt.position, queryImpl.endAt.inclusive)
|
|
5842
5841
|
: null;
|
|
5843
5842
|
const endAt = queryImpl.startAt
|
|
5844
|
-
? new Bound(queryImpl.startAt.position,
|
|
5843
|
+
? new Bound(queryImpl.startAt.position, queryImpl.startAt.inclusive)
|
|
5845
5844
|
: null;
|
|
5846
5845
|
// Now return as a LimitType.First query.
|
|
5847
5846
|
queryImpl.memoizedTarget = newTarget(queryImpl.path, queryImpl.collectionGroup, orderBys, queryImpl.filters, queryImpl.limit, startAt, endAt);
|
|
@@ -6112,8 +6111,12 @@ function mutableDocumentMap() {
|
|
|
6112
6111
|
return EMPTY_MUTABLE_DOCUMENT_MAP;
|
|
6113
6112
|
}
|
|
6114
6113
|
const EMPTY_DOCUMENT_MAP = new SortedMap(DocumentKey.comparator);
|
|
6115
|
-
function documentMap() {
|
|
6116
|
-
|
|
6114
|
+
function documentMap(...docs) {
|
|
6115
|
+
let map = EMPTY_DOCUMENT_MAP;
|
|
6116
|
+
for (const doc of docs) {
|
|
6117
|
+
map = map.insert(doc.key, doc);
|
|
6118
|
+
}
|
|
6119
|
+
return map;
|
|
6117
6120
|
}
|
|
6118
6121
|
function newOverlayMap() {
|
|
6119
6122
|
return new ObjectMap(key => key.toString(), (l, r) => l.isEqual(r));
|
|
@@ -10018,6 +10021,9 @@ class MemoryIndexManager {
|
|
|
10018
10021
|
// Field indices are not supported with memory persistence.
|
|
10019
10022
|
return PersistencePromise.resolve(null);
|
|
10020
10023
|
}
|
|
10024
|
+
getMinOffset(transaction, target) {
|
|
10025
|
+
return PersistencePromise.resolve(IndexOffset.min());
|
|
10026
|
+
}
|
|
10021
10027
|
updateCollectionGroup(transaction, collectionGroup, offset) {
|
|
10022
10028
|
// Field indices are not supported with memory persistence.
|
|
10023
10029
|
return PersistencePromise.resolve();
|
|
@@ -10193,7 +10199,7 @@ class IndexedDbIndexManager {
|
|
|
10193
10199
|
const lowerBoundEncoded = this.encodeBound(index, subTarget, lowerBound);
|
|
10194
10200
|
const upperBoundEncoded = this.encodeBound(index, subTarget, upperBound);
|
|
10195
10201
|
const notInEncoded = this.encodeValues(index, subTarget, notInValues);
|
|
10196
|
-
const indexRanges = this.generateIndexRanges(index.indexId, arrayValues, lowerBoundEncoded,
|
|
10202
|
+
const indexRanges = this.generateIndexRanges(index.indexId, arrayValues, lowerBoundEncoded, lowerBound.inclusive, upperBoundEncoded, upperBound.inclusive, notInEncoded);
|
|
10197
10203
|
return PersistencePromise.forEach(indexRanges, (indexRange) => {
|
|
10198
10204
|
return indexEntries
|
|
10199
10205
|
.loadFirst(indexRange, target.limit)
|
|
@@ -10231,22 +10237,18 @@ class IndexedDbIndexManager {
|
|
|
10231
10237
|
// index range per value in an ARRAY_CONTAINS or ARRAY_CONTAINS_ANY filter
|
|
10232
10238
|
// combined with the values from the query bounds.
|
|
10233
10239
|
const totalScans = (arrayValues != null ? arrayValues.length : 1) *
|
|
10234
|
-
Math.max(lowerBounds
|
|
10240
|
+
Math.max(lowerBounds.length, upperBounds.length);
|
|
10235
10241
|
const scansPerArrayElement = totalScans / (arrayValues != null ? arrayValues.length : 1);
|
|
10236
10242
|
const indexRanges = [];
|
|
10237
10243
|
for (let i = 0; i < totalScans; ++i) {
|
|
10238
10244
|
const arrayValue = arrayValues
|
|
10239
10245
|
? this.encodeSingleElement(arrayValues[i / scansPerArrayElement])
|
|
10240
10246
|
: EMPTY_VALUE;
|
|
10241
|
-
const lowerBound = lowerBounds
|
|
10242
|
-
|
|
10243
|
-
|
|
10244
|
-
|
|
10245
|
-
|
|
10246
|
-
: this.generateEmptyBound(indexId + 1);
|
|
10247
|
-
indexRanges.push(...this.createRange(lowerBound, upperBound, notInValues.map((notIn // make non-nullable
|
|
10248
|
-
) => this.generateLowerBound(indexId, arrayValue, notIn,
|
|
10249
|
-
/* inclusive= */ true))));
|
|
10247
|
+
const lowerBound = this.generateLowerBound(indexId, arrayValue, lowerBounds[i % scansPerArrayElement], lowerBoundInclusive);
|
|
10248
|
+
const upperBound = this.generateUpperBound(indexId, arrayValue, upperBounds[i % scansPerArrayElement], upperBoundInclusive);
|
|
10249
|
+
const notInBound = notInValues.map(notIn => this.generateLowerBound(indexId, arrayValue, notIn,
|
|
10250
|
+
/* inclusive= */ true));
|
|
10251
|
+
indexRanges.push(...this.createRange(lowerBound, upperBound, notInBound));
|
|
10250
10252
|
}
|
|
10251
10253
|
return indexRanges;
|
|
10252
10254
|
}
|
|
@@ -10260,13 +10262,6 @@ class IndexedDbIndexManager {
|
|
|
10260
10262
|
const entry = new IndexEntry(indexId, DocumentKey.empty(), arrayValue, directionalValue);
|
|
10261
10263
|
return inclusive ? entry.successor() : entry;
|
|
10262
10264
|
}
|
|
10263
|
-
/**
|
|
10264
|
-
* Generates an empty bound that scopes the index scan to the current index
|
|
10265
|
-
* and user.
|
|
10266
|
-
*/
|
|
10267
|
-
generateEmptyBound(indexId) {
|
|
10268
|
-
return new IndexEntry(indexId, DocumentKey.empty(), EMPTY_VALUE, EMPTY_VALUE);
|
|
10269
|
-
}
|
|
10270
10265
|
getFieldIndex(transaction, target) {
|
|
10271
10266
|
const targetIndexMatcher = new TargetIndexMatcher(target);
|
|
10272
10267
|
const collectionGroup = target.collectionGroup != null
|
|
@@ -10286,15 +10281,18 @@ class IndexedDbIndexManager {
|
|
|
10286
10281
|
});
|
|
10287
10282
|
}
|
|
10288
10283
|
getIndexType(transaction, target) {
|
|
10289
|
-
|
|
10290
|
-
return this.
|
|
10291
|
-
|
|
10292
|
-
|
|
10293
|
-
|
|
10294
|
-
|
|
10295
|
-
|
|
10296
|
-
|
|
10297
|
-
|
|
10284
|
+
let indexType = 2 /* FULL */;
|
|
10285
|
+
return PersistencePromise.forEach(this.getSubTargets(target), (target) => {
|
|
10286
|
+
return this.getFieldIndex(transaction, target).next(index => {
|
|
10287
|
+
if (!index) {
|
|
10288
|
+
indexType = 0 /* NONE */;
|
|
10289
|
+
}
|
|
10290
|
+
else if (indexType !== 0 /* NONE */ &&
|
|
10291
|
+
index.fields.length < targetGetSegmentCount(target)) {
|
|
10292
|
+
indexType = 1 /* PARTIAL */;
|
|
10293
|
+
}
|
|
10294
|
+
});
|
|
10295
|
+
}).next(() => indexType);
|
|
10298
10296
|
}
|
|
10299
10297
|
/**
|
|
10300
10298
|
* Returns the byte encoded form of the directional values in the field index.
|
|
@@ -10358,9 +10356,6 @@ class IndexedDbIndexManager {
|
|
|
10358
10356
|
* queries, a list of possible values is returned.
|
|
10359
10357
|
*/
|
|
10360
10358
|
encodeBound(fieldIndex, target, bound) {
|
|
10361
|
-
if (bound == null) {
|
|
10362
|
-
return null;
|
|
10363
|
-
}
|
|
10364
10359
|
return this.encodeValues(fieldIndex, target, bound.position);
|
|
10365
10360
|
}
|
|
10366
10361
|
/** Returns the byte representation for the provided encoders. */
|
|
@@ -10555,7 +10550,7 @@ class IndexedDbIndexManager {
|
|
|
10555
10550
|
* '[foo > 2 && foo != 3]` becomes `[foo > 2 && < 3, foo > 3]`.
|
|
10556
10551
|
*/
|
|
10557
10552
|
createRange(lower, upper, notInValues) {
|
|
10558
|
-
// The
|
|
10553
|
+
// The notIn values need to be sorted and unique so that we can return a
|
|
10559
10554
|
// sorted set of non-overlapping ranges.
|
|
10560
10555
|
notInValues = notInValues
|
|
10561
10556
|
.sort((l, r) => indexEntryComparator(l, r))
|
|
@@ -10601,6 +10596,20 @@ class IndexedDbIndexManager {
|
|
|
10601
10596
|
}
|
|
10602
10597
|
return ranges;
|
|
10603
10598
|
}
|
|
10599
|
+
getMinOffset(transaction, target) {
|
|
10600
|
+
let offset;
|
|
10601
|
+
return PersistencePromise.forEach(this.getSubTargets(target), (target) => {
|
|
10602
|
+
return this.getFieldIndex(transaction, target).next(index => {
|
|
10603
|
+
if (!index) {
|
|
10604
|
+
offset = IndexOffset.min();
|
|
10605
|
+
}
|
|
10606
|
+
else if (!offset ||
|
|
10607
|
+
indexOffsetComparator(index.indexState.offset, offset) < 0) {
|
|
10608
|
+
offset = index.indexState.offset;
|
|
10609
|
+
}
|
|
10610
|
+
});
|
|
10611
|
+
}).next(() => offset);
|
|
10612
|
+
}
|
|
10604
10613
|
}
|
|
10605
10614
|
/**
|
|
10606
10615
|
* Helper to get a typed SimpleDbStore for the collectionParents
|
|
@@ -13771,7 +13780,7 @@ class LocalStoreImpl {
|
|
|
13771
13780
|
this.mutationQueue = this.persistence.getMutationQueue(user, this.indexManager);
|
|
13772
13781
|
this.localDocuments = new LocalDocumentsView(this.remoteDocuments, this.mutationQueue, this.indexManager);
|
|
13773
13782
|
this.remoteDocuments.setIndexManager(this.indexManager);
|
|
13774
|
-
this.queryEngine.
|
|
13783
|
+
this.queryEngine.initialize(this.localDocuments, this.indexManager);
|
|
13775
13784
|
}
|
|
13776
13785
|
collectGarbage(garbageCollector) {
|
|
13777
13786
|
return this.persistence.runTransaction('Collect garbage', 'readwrite-primary', txn => garbageCollector.collect(txn, this.targetDataByTarget));
|
|
@@ -15513,10 +15522,30 @@ class MemoryEagerDelegate {
|
|
|
15513
15522
|
* limitations under the License.
|
|
15514
15523
|
*/
|
|
15515
15524
|
/**
|
|
15516
|
-
*
|
|
15517
|
-
*
|
|
15518
|
-
*
|
|
15519
|
-
*
|
|
15525
|
+
* The Firestore query engine.
|
|
15526
|
+
*
|
|
15527
|
+
* Firestore queries can be executed in three modes. The Query Engine determines
|
|
15528
|
+
* what mode to use based on what data is persisted. The mode only determines
|
|
15529
|
+
* the runtime complexity of the query - the result set is equivalent across all
|
|
15530
|
+
* implementations.
|
|
15531
|
+
*
|
|
15532
|
+
* The Query engine will use indexed-based execution if a user has configured
|
|
15533
|
+
* any index that can be used to execute query (via `setIndexConfiguration()`).
|
|
15534
|
+
* Otherwise, the engine will try to optimize the query by re-using a previously
|
|
15535
|
+
* persisted query result. If that is not possible, the query will be executed
|
|
15536
|
+
* via a full collection scan.
|
|
15537
|
+
*
|
|
15538
|
+
* Index-based execution is the default when available. The query engine
|
|
15539
|
+
* supports partial indexed execution and merges the result from the index
|
|
15540
|
+
* lookup with documents that have not yet been indexed. The index evaluation
|
|
15541
|
+
* matches the backend's format and as such, the SDK can use indexing for all
|
|
15542
|
+
* queries that the backend supports.
|
|
15543
|
+
*
|
|
15544
|
+
* If no index exists, the query engine tries to take advantage of the target
|
|
15545
|
+
* document mapping in the TargetCache. These mappings exists for all queries
|
|
15546
|
+
* that have been synced with the backend at least once and allow the query
|
|
15547
|
+
* engine to only read documents that previously matched a query plus any
|
|
15548
|
+
* documents that were edited after the query was last listened to.
|
|
15520
15549
|
*
|
|
15521
15550
|
* There are some cases when this optimization is not guaranteed to produce
|
|
15522
15551
|
* the same results as full collection scans. In these cases, query
|
|
@@ -15531,16 +15560,41 @@ class MemoryEagerDelegate {
|
|
|
15531
15560
|
* - Queries that have never been CURRENT or free of limbo documents.
|
|
15532
15561
|
*/
|
|
15533
15562
|
class QueryEngine {
|
|
15563
|
+
constructor() {
|
|
15564
|
+
this.initialized = false;
|
|
15565
|
+
}
|
|
15534
15566
|
/** Sets the document view to query against. */
|
|
15535
|
-
|
|
15567
|
+
initialize(localDocuments, indexManager) {
|
|
15536
15568
|
this.localDocumentsView = localDocuments;
|
|
15569
|
+
this.indexManager = indexManager;
|
|
15570
|
+
this.initialized = true;
|
|
15537
15571
|
}
|
|
15538
15572
|
/** Returns all local documents matching the specified query. */
|
|
15539
15573
|
getDocumentsMatchingQuery(transaction, query, lastLimboFreeSnapshotVersion, remoteKeys) {
|
|
15540
|
-
|
|
15541
|
-
|
|
15542
|
-
|
|
15543
|
-
|
|
15574
|
+
return this.performQueryUsingIndex(transaction, query)
|
|
15575
|
+
.next(result => result
|
|
15576
|
+
? result
|
|
15577
|
+
: this.performQueryUsingRemoteKeys(transaction, query, remoteKeys, lastLimboFreeSnapshotVersion))
|
|
15578
|
+
.next(result => result ? result : this.executeFullCollectionScan(transaction, query));
|
|
15579
|
+
}
|
|
15580
|
+
/**
|
|
15581
|
+
* Performs an indexed query that evaluates the query based on a collection's
|
|
15582
|
+
* persisted index values. Returns `null` if an index is not available.
|
|
15583
|
+
*/
|
|
15584
|
+
performQueryUsingIndex(transaction, query) {
|
|
15585
|
+
{
|
|
15586
|
+
return PersistencePromise.resolve(null);
|
|
15587
|
+
}
|
|
15588
|
+
}
|
|
15589
|
+
/**
|
|
15590
|
+
* Performs a query based on the target's persisted query mapping. Returns
|
|
15591
|
+
* `null` if the mapping is not available or cannot be used.
|
|
15592
|
+
*/
|
|
15593
|
+
performQueryUsingRemoteKeys(transaction, query, remoteKeys, lastLimboFreeSnapshotVersion) {
|
|
15594
|
+
if (queryMatchesAllDocuments(query)) {
|
|
15595
|
+
// Queries that match all documents don't benefit from using
|
|
15596
|
+
// key-based lookups. It is more efficient to scan all documents in a
|
|
15597
|
+
// collection, rather than to perform individual lookups.
|
|
15544
15598
|
return this.executeFullCollectionScan(transaction, query);
|
|
15545
15599
|
}
|
|
15546
15600
|
// Queries that have never seen a snapshot without limbo free documents
|
|
@@ -15550,8 +15604,7 @@ class QueryEngine {
|
|
|
15550
15604
|
}
|
|
15551
15605
|
return this.localDocumentsView.getDocuments(transaction, remoteKeys).next(documents => {
|
|
15552
15606
|
const previousResults = this.applyQuery(query, documents);
|
|
15553
|
-
if ((
|
|
15554
|
-
this.needsRefill(query.limitType, previousResults, remoteKeys, lastLimboFreeSnapshotVersion)) {
|
|
15607
|
+
if (this.needsRefill(query, previousResults, remoteKeys, lastLimboFreeSnapshotVersion)) {
|
|
15555
15608
|
return this.executeFullCollectionScan(transaction, query);
|
|
15556
15609
|
}
|
|
15557
15610
|
if (getLogLevel() <= LogLevel.DEBUG) {
|
|
@@ -15559,15 +15612,7 @@ class QueryEngine {
|
|
|
15559
15612
|
}
|
|
15560
15613
|
// Retrieve all results for documents that were updated since the last
|
|
15561
15614
|
// limbo-document free remote snapshot.
|
|
15562
|
-
return this.
|
|
15563
|
-
// We merge `previousResults` into `updateResults`, since
|
|
15564
|
-
// `updateResults` is already a DocumentMap. If a document is
|
|
15565
|
-
// contained in both lists, then its contents are the same.
|
|
15566
|
-
previousResults.forEach(doc => {
|
|
15567
|
-
updatedResults = updatedResults.insert(doc.key, doc);
|
|
15568
|
-
});
|
|
15569
|
-
return updatedResults;
|
|
15570
|
-
});
|
|
15615
|
+
return this.appendRemainingResults(transaction, previousResults, query, newIndexOffsetSuccessorFromReadTime(lastLimboFreeSnapshotVersion, INITIAL_LARGEST_BATCH_ID));
|
|
15571
15616
|
});
|
|
15572
15617
|
}
|
|
15573
15618
|
/** Applies the query filter and sorting to the provided documents. */
|
|
@@ -15586,6 +15631,7 @@ class QueryEngine {
|
|
|
15586
15631
|
* Determines if a limit query needs to be refilled from cache, making it
|
|
15587
15632
|
* ineligible for index-free execution.
|
|
15588
15633
|
*
|
|
15634
|
+
* @param query The query.
|
|
15589
15635
|
* @param sortedPreviousResults - The documents that matched the query when it
|
|
15590
15636
|
* was last synchronized, sorted by the query's comparator.
|
|
15591
15637
|
* @param remoteKeys - The document keys that matched the query at the last
|
|
@@ -15593,10 +15639,14 @@ class QueryEngine {
|
|
|
15593
15639
|
* @param limboFreeSnapshotVersion - The version of the snapshot when the
|
|
15594
15640
|
* query was last synchronized.
|
|
15595
15641
|
*/
|
|
15596
|
-
needsRefill(
|
|
15597
|
-
|
|
15598
|
-
|
|
15642
|
+
needsRefill(query, sortedPreviousResults, remoteKeys, limboFreeSnapshotVersion) {
|
|
15643
|
+
if (query.limit === null) {
|
|
15644
|
+
// Queries without limits do not need to be refilled.
|
|
15645
|
+
return false;
|
|
15646
|
+
}
|
|
15599
15647
|
if (remoteKeys.size !== sortedPreviousResults.size) {
|
|
15648
|
+
// The query needs to be refilled if a previously matching document no
|
|
15649
|
+
// longer matches.
|
|
15600
15650
|
return true;
|
|
15601
15651
|
}
|
|
15602
15652
|
// Limit queries are not eligible for index-free query execution if there is
|
|
@@ -15607,7 +15657,7 @@ class QueryEngine {
|
|
|
15607
15657
|
// the boundary of the limit itself did not change and documents from cache
|
|
15608
15658
|
// will continue to be "rejected" by this boundary. Therefore, we can ignore
|
|
15609
15659
|
// any modifications that don't affect the last document.
|
|
15610
|
-
const docAtLimitEdge = limitType === "F" /* First */
|
|
15660
|
+
const docAtLimitEdge = query.limitType === "F" /* First */
|
|
15611
15661
|
? sortedPreviousResults.last()
|
|
15612
15662
|
: sortedPreviousResults.first();
|
|
15613
15663
|
if (!docAtLimitEdge) {
|
|
@@ -15623,6 +15673,22 @@ class QueryEngine {
|
|
|
15623
15673
|
}
|
|
15624
15674
|
return this.localDocumentsView.getDocumentsMatchingQuery(transaction, query, IndexOffset.min());
|
|
15625
15675
|
}
|
|
15676
|
+
/**
|
|
15677
|
+
* Combines the results from an indexed execution with the remaining documents
|
|
15678
|
+
* that have not yet been indexed.
|
|
15679
|
+
*/
|
|
15680
|
+
appendRemainingResults(transaction, indexedResults, query, offset) {
|
|
15681
|
+
// Retrieve all results for documents that were updated since the offset.
|
|
15682
|
+
return this.localDocumentsView
|
|
15683
|
+
.getDocumentsMatchingQuery(transaction, query, offset)
|
|
15684
|
+
.next(remainingResults => {
|
|
15685
|
+
// Merge with existing results
|
|
15686
|
+
indexedResults.forEach(d => {
|
|
15687
|
+
remainingResults = remainingResults.insert(d.key, d);
|
|
15688
|
+
});
|
|
15689
|
+
return remainingResults;
|
|
15690
|
+
});
|
|
15691
|
+
}
|
|
15626
15692
|
}
|
|
15627
15693
|
|
|
15628
15694
|
/**
|
|
@@ -21882,10 +21948,12 @@ class View {
|
|
|
21882
21948
|
//
|
|
21883
21949
|
// Note that this should never get used in a refill (when previousChanges is
|
|
21884
21950
|
// set), because there will only be adds -- no deletes or updates.
|
|
21885
|
-
const lastDocInLimit =
|
|
21951
|
+
const lastDocInLimit = this.query.limitType === "F" /* First */ &&
|
|
21952
|
+
oldDocumentSet.size === this.query.limit
|
|
21886
21953
|
? oldDocumentSet.last()
|
|
21887
21954
|
: null;
|
|
21888
|
-
const firstDocInLimit =
|
|
21955
|
+
const firstDocInLimit = this.query.limitType === "L" /* Last */ &&
|
|
21956
|
+
oldDocumentSet.size === this.query.limit
|
|
21889
21957
|
? oldDocumentSet.first()
|
|
21890
21958
|
: null;
|
|
21891
21959
|
docChanges.inorderTraversal((key, entry) => {
|
|
@@ -21958,9 +22026,9 @@ class View {
|
|
|
21958
22026
|
}
|
|
21959
22027
|
});
|
|
21960
22028
|
// Drop documents out to meet limit/limitToLast requirement.
|
|
21961
|
-
if (
|
|
22029
|
+
if (this.query.limit !== null) {
|
|
21962
22030
|
while (newDocumentSet.size > this.query.limit) {
|
|
21963
|
-
const oldDoc =
|
|
22031
|
+
const oldDoc = this.query.limitType === "F" /* First */
|
|
21964
22032
|
? newDocumentSet.last()
|
|
21965
22033
|
: newDocumentSet.first();
|
|
21966
22034
|
newDocumentSet = newDocumentSet.delete(oldDoc.key);
|
|
@@ -23961,18 +24029,18 @@ class Transaction$2 {
|
|
|
23961
24029
|
* See the License for the specific language governing permissions and
|
|
23962
24030
|
* limitations under the License.
|
|
23963
24031
|
*/
|
|
23964
|
-
const DEFAULT_MAX_ATTEMPTS_COUNT = 5;
|
|
23965
24032
|
/**
|
|
23966
24033
|
* TransactionRunner encapsulates the logic needed to run and retry transactions
|
|
23967
24034
|
* with backoff.
|
|
23968
24035
|
*/
|
|
23969
24036
|
class TransactionRunner {
|
|
23970
|
-
constructor(asyncQueue, datastore, updateFunction, deferred) {
|
|
24037
|
+
constructor(asyncQueue, datastore, options, updateFunction, deferred) {
|
|
23971
24038
|
this.asyncQueue = asyncQueue;
|
|
23972
24039
|
this.datastore = datastore;
|
|
24040
|
+
this.options = options;
|
|
23973
24041
|
this.updateFunction = updateFunction;
|
|
23974
24042
|
this.deferred = deferred;
|
|
23975
|
-
this.attemptsRemaining =
|
|
24043
|
+
this.attemptsRemaining = options.maxAttempts;
|
|
23976
24044
|
this.backoff = new ExponentialBackoff(this.asyncQueue, "transaction_retry" /* TransactionRetry */);
|
|
23977
24045
|
}
|
|
23978
24046
|
/** Runs the transaction and sets the result on deferred. */
|
|
@@ -24330,11 +24398,11 @@ function firestoreClientAddSnapshotsInSyncListener(client, observer) {
|
|
|
24330
24398
|
* been committed. For this reason, it is required that all reads are
|
|
24331
24399
|
* performed before any writes. Transactions must be performed while online.
|
|
24332
24400
|
*/
|
|
24333
|
-
function firestoreClientTransaction(client, updateFunction) {
|
|
24401
|
+
function firestoreClientTransaction(client, updateFunction, options) {
|
|
24334
24402
|
const deferred = new Deferred();
|
|
24335
24403
|
client.asyncQueue.enqueueAndForget(async () => {
|
|
24336
24404
|
const datastore = await getDatastore(client);
|
|
24337
|
-
new TransactionRunner(client.asyncQueue, datastore, updateFunction, deferred).run();
|
|
24405
|
+
new TransactionRunner(client.asyncQueue, datastore, options, updateFunction, deferred).run();
|
|
24338
24406
|
});
|
|
24339
24407
|
return deferred.promise;
|
|
24340
24408
|
}
|
|
@@ -27091,7 +27159,8 @@ function snapshotEqual(left, right) {
|
|
|
27091
27159
|
* limitations under the License.
|
|
27092
27160
|
*/
|
|
27093
27161
|
function validateHasExplicitOrderByForLimitToLast(query) {
|
|
27094
|
-
if (
|
|
27162
|
+
if (query.limitType === "L" /* Last */ &&
|
|
27163
|
+
query.explicitOrderBy.length === 0) {
|
|
27095
27164
|
throw new FirestoreError(Code.UNIMPLEMENTED, 'limitToLast() queries require specifying at least one orderBy() clause');
|
|
27096
27165
|
}
|
|
27097
27166
|
}
|
|
@@ -27533,6 +27602,31 @@ function validateOrderByAndInequalityMatch(baseQuery, inequality, orderBy) {
|
|
|
27533
27602
|
}
|
|
27534
27603
|
}
|
|
27535
27604
|
|
|
27605
|
+
/**
|
|
27606
|
+
* @license
|
|
27607
|
+
* Copyright 2022 Google LLC
|
|
27608
|
+
*
|
|
27609
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
27610
|
+
* you may not use this file except in compliance with the License.
|
|
27611
|
+
* You may obtain a copy of the License at
|
|
27612
|
+
*
|
|
27613
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
27614
|
+
*
|
|
27615
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
27616
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
27617
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
27618
|
+
* See the License for the specific language governing permissions and
|
|
27619
|
+
* limitations under the License.
|
|
27620
|
+
*/
|
|
27621
|
+
const DEFAULT_TRANSACTION_OPTIONS = {
|
|
27622
|
+
maxAttempts: 5
|
|
27623
|
+
};
|
|
27624
|
+
function validateTransactionOptions(options) {
|
|
27625
|
+
if (options.maxAttempts < 1) {
|
|
27626
|
+
throw new FirestoreError(Code.INVALID_ARGUMENT, 'Max attempts must be at least 1');
|
|
27627
|
+
}
|
|
27628
|
+
}
|
|
27629
|
+
|
|
27536
27630
|
/**
|
|
27537
27631
|
* @license
|
|
27538
27632
|
* Copyright 2020 Google LLC
|
|
@@ -28254,10 +28348,12 @@ class Transaction extends Transaction$1 {
|
|
|
28254
28348
|
* `updateFunction `is returned here. Otherwise, if the transaction failed, a
|
|
28255
28349
|
* rejected promise with the corresponding failure error is returned.
|
|
28256
28350
|
*/
|
|
28257
|
-
function runTransaction(firestore, updateFunction) {
|
|
28351
|
+
function runTransaction(firestore, updateFunction, options) {
|
|
28258
28352
|
firestore = cast(firestore, Firestore);
|
|
28353
|
+
const optionsWithDefaults = Object.assign(Object.assign({}, DEFAULT_TRANSACTION_OPTIONS), options);
|
|
28354
|
+
validateTransactionOptions(optionsWithDefaults);
|
|
28259
28355
|
const client = ensureFirestoreConfigured(firestore);
|
|
28260
|
-
return firestoreClientTransaction(client, internalTransaction => updateFunction(new Transaction(firestore, internalTransaction)));
|
|
28356
|
+
return firestoreClientTransaction(client, internalTransaction => updateFunction(new Transaction(firestore, internalTransaction)), optionsWithDefaults);
|
|
28261
28357
|
}
|
|
28262
28358
|
|
|
28263
28359
|
/**
|