Skip to content

Commit

Permalink
fix: run pagination in optimistic writes (#23)
Browse files Browse the repository at this point in the history
fix: run pagination in optimistic writes
  • Loading branch information
Bobby authored Aug 19, 2021
2 parents b4f52d9 + ea17e97 commit 8d74020
Showing 1 changed file with 39 additions and 6 deletions.
45 changes: 39 additions & 6 deletions src/reducers/cacheReducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ const verbose = debug('rrfVerbose:cache');
*/

const isTimestamp = (a) => a instanceof Object && a.seconds !== undefined;
const formatTimestamp = ({ seconds } = {}) =>
seconds &&
new Intl.DateTimeFormat('en-US', { dateStyle: 'short' }).format(
new Date(seconds * 1000),
);

const PROCESSES = {
'<': (a, b) => a < b,
Expand Down Expand Up @@ -272,16 +277,37 @@ const xfLimit = ({ limit, endAt, endBefore }) => {
* @returns {xFormFilter} - transducer
*/
const xfPaginate = (query, getDoc) => {
const { orderBy: order, startAt, startAfter, endAt, endBefore, via } = query;
const {
orderBy: order,
limit,
startAt,
startAfter,
endAt,
endBefore,
via,
} = query;

const isOptimisticRead = !via || via === 'memory';
const start = startAt || startAfter;
const end = endAt || endBefore;
const isAfter = startAfter !== undefined;
const isBefore = endBefore !== undefined;
const needsPagination = start || end || false;

if (!needsPagination || !order || !isOptimisticRead) return identity;
if (!needsPagination || !order) return identity;

let prop = null;
if (verbose.enabled) {
if (startAt) prop = 'startAt';
else if (startAfter) prop = 'startAfter';
else if (endAt) prop = 'endAt';
else if (endBefore) prop = 'endBefore';

verbose(
`paginate ${prop}:${formatTimestamp(needsPagination)} ` +
`order:[${query?.orderBy?.[0]}, ${query?.orderBy?.[1]}] ` +
`via:${via}`,
);
}

const isFlat = typeof order[0] === 'string';
const orders = isFlat ? [order] : order;
Expand All @@ -291,15 +317,20 @@ const xfPaginate = (query, getDoc) => {
if (value === undefined) return false;

// TODO: add support for document refs
const proc = isTimestamp(document[field])
? PROCESSES_TIMESTAMP
: PROCESSES;
const isTime = isTimestamp(document[field]);
const proc = isTime ? PROCESSES_TIMESTAMP : PROCESSES;
let compare = process['=='];
if (startAt || endAt) compare = proc[sort === 'desc' ? '<=' : '>='];
if (startAfter || endBefore) compare = proc[sort === 'desc' ? '<' : '>'];

const isMatched = compare(document[field], value);
if (isMatched) {
if (verbose.enabled) {
const val = isTime
? formatTimestamp(document[field])
: document[field];
verbose(`${prop}: ${document.id}.${field} = ${val}`);
}
return true;
}
}) !== undefined;
Expand All @@ -309,6 +340,8 @@ const xfPaginate = (query, getDoc) => {
let started = start === undefined;

tuples.forEach(([path, id]) => {
if (limit && results.length >= limit) return;

if (!started && start) {
if (isPaginateMatched(getDoc(path, id), start, undefined, isAfter)) {
started = true;
Expand Down

0 comments on commit 8d74020

Please sign in to comment.