add _selectWhile with proper "while" semantics

the existing _selectWhile method was more like _selectUntil,
which is what we want for _selectLimit but not for selectWhile(Reverse)

The changes we had made before also broke _selectLimit as it would
look at the results length before the value got added so you
always got 1 value more than requested, breaking sync.
This commit is contained in:
Bruno Windels 2020-08-19 18:25:49 +02:00
parent 79363ed1d7
commit fe7cc08287

View file

@ -62,11 +62,11 @@ export class QueryTarget {
} }
selectWhile(range, predicate) { selectWhile(range, predicate) {
return this._selectWhile(range, predicate, "next", false); return this._selectWhile(range, predicate, "next");
} }
selectWhileReverse(range, predicate) { selectWhileReverse(range, predicate) {
return this._selectWhile(range, predicate, "prev", false); return this._selectWhile(range, predicate, "prev");
} }
async selectAll(range, direction) { async selectAll(range, direction) {
@ -151,20 +151,31 @@ export class QueryTarget {
} }
_selectLimit(range, amount, direction) { _selectLimit(range, amount, direction) {
return this._selectWhile(range, (results) => { return this._selectUntil(range, (results) => {
return results.length === amount; return results.length === amount;
}, direction, true); }, direction);
} }
async _selectWhile(range, predicate, direction, includeFailingPredicateResult) { async _selectUntil(range, predicate, direction) {
const cursor = this._openCursor(range, direction); const cursor = this._openCursor(range, direction);
const results = []; const results = [];
await iterateCursor(cursor, (value) => { await iterateCursor(cursor, (value) => {
const passesPredicate = predicate(results, value); results.push(value);
if (passesPredicate || includeFailingPredicateResult) { return {done: predicate(results, value)};
});
return results;
}
// allows you to fetch one too much that won't get added when the predicate fails
async _selectWhile(range, predicate, direction) {
const cursor = this._openCursor(range, direction);
const results = [];
await iterateCursor(cursor, (value) => {
const passesPredicate = predicate(value);
if (passesPredicate) {
results.push(value); results.push(value);
} }
return {done: passesPredicate}; return {done: !passesPredicate};
}); });
return results; return results;
} }