dwFakeWindow<T extends DwDataObject> function
DwWindowResult<T>
dwFakeWindow<T extends DwDataObject>(
- List<
T> newestFirst, - DwWindowRequest<
T, Object, Object> request, - DwPageQuery? page
The window of newestFirst a DwWindowRequest call asks for, with the
cursors a DartWay server builds from the request's positionOf.
newestFirst must be ordered by that position, descending. Around an anchor
the window holds the anchor row and the rows older than it, with up to
half of the page newer than it.
Implementation
DwWindowResult<T> dwFakeWindow<T extends DwDataObject>(
List<T> newestFirst,
DwWindowRequest<T, Object, Object> request,
DwPageQuery? page,
) {
final query = page is DwWindowQuery ? page : const DwWindowQuery.newest();
final size = request.servedPageSize(query.pageSize);
DwWindowCursor keyOf(T row) {
final (:sortValue, :id) = request.positionOf(row);
return DwWindowCursor(sortValue, id);
}
// Positions in newest-first order: rows before `index` are newer.
int firstNotNewerThan(DwWindowCursor cursor) {
final index = newestFirst.indexWhere(
(row) => _compare(keyOf(row), cursor) <= 0,
);
return index < 0 ? newestFirst.length : index;
}
final int start;
final int end;
switch ((query.direction, query.cursor)) {
case (DwWindowDirection.around, null):
start = 0;
end = size;
case (DwWindowDirection.around, final String anchor):
final at = firstNotNewerThan(DwWindowCursor.decode(anchor));
final newer = size ~/ 2;
start = at - newer < 0 ? 0 : at - newer;
end = start + size;
case (DwWindowDirection.older, final String before):
final cursor = DwWindowCursor.decode(before);
final at = newestFirst.indexWhere(
(row) => _compare(keyOf(row), cursor) < 0,
);
start = at < 0 ? newestFirst.length : at;
end = start + size;
case (DwWindowDirection.newer, final String after):
final at = firstNotNewerThan(DwWindowCursor.decode(after));
end = at;
start = end - size < 0 ? 0 : end - size;
default:
throw ArgumentError('A window read past an end names its cursor');
}
final clampedEnd = end > newestFirst.length ? newestFirst.length : end;
final rows = newestFirst.sublist(start, clampedEnd);
if (rows.isEmpty) return DwWindowResult<T>(rows);
return DwWindowResult<T>(
rows,
olderCursor: clampedEnd < newestFirst.length
? keyOf(rows.last).encoded
: null,
newerCursor: start > 0 ? keyOf(rows.first).encoded : null,
);
}