Skip to content

Commit 86da9e1

Browse files
author
Bobby
authored
feat: optimistic reads
feat: optimistic reads
2 parents 2d8de81 + 18175b3 commit 86da9e1

File tree

2 files changed

+23
-16
lines changed

2 files changed

+23
-16
lines changed

src/reducers/cacheReducer.js

+21-14
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ const PROCESSES = {
105105
'>=': (a, b) => a >= b,
106106
'>': (a, b) => a > b,
107107
'array-contains': (a, b) => a.includes(b),
108-
in: (a, b) => a.includes(b),
108+
in: (a, b) => a && a.includes(b),
109109
'array-contains-any': (a, b) => b.some((b1) => a.includes(b1)),
110110
'not-in': (a, b) => !b.includes(a),
111111
'*': () => true,
@@ -150,7 +150,16 @@ const fieldsTransducer = (fields) =>
150150
const orderTransducer = (order) => {
151151
const isFlat = typeof order[0] === 'string';
152152
const orders = isFlat ? [order] : order;
153-
return partialRight.apply(null, [orderBy, ...zip.apply(null, orders)]);
153+
const [fields, direction] = zip(
154+
...orders.map(([field, dir]) => [
155+
(data) =>
156+
typeof data[field] === 'string'
157+
? data[field].toLowerCase()
158+
: data[field],
159+
dir || 'asc',
160+
]),
161+
);
162+
return partialRight(map, (docs) => orderBy(docs, fields, direction));
154163
};
155164

156165
/**
@@ -288,6 +297,7 @@ function buildTransducer(overrides, query) {
288297
} = query;
289298

290299
const useOverrides =
300+
ordered === undefined ||
291301
Object.keys((overrides || {})[collection] || {}).length > 0;
292302

293303
const xfPopulate = !populates
@@ -299,7 +309,7 @@ function buildTransducer(overrides, query) {
299309

300310
const xfApplyOverrides = !useOverrides
301311
? null
302-
: overridesTransducers(overrides, collection);
312+
: overridesTransducers(overrides || { [collection]: [] }, collection);
303313
const xfFilter =
304314
!useOverrides || filterTransducers(!where ? ['', '*', ''] : where);
305315
const xfOrder = !useOverrides || !order ? null : orderTransducer(order);
@@ -313,7 +323,7 @@ function buildTransducer(overrides, query) {
313323
compact([
314324
xfPopulate,
315325
xfGetCollection,
316-
partialRight(map, (db) => createDraft(db)),
326+
partialRight(map, (db) => createDraft(db || {})),
317327
...xfApplyOverrides,
318328
partialRight(map, (db) => finishDraft(db)),
319329
...xfFilter,
@@ -541,7 +551,7 @@ function cleanOverride(draft, { path, id, data }) {
541551

542552
const initialize = (state, { action, key, path }) =>
543553
produce(state, (draft) => {
544-
const done = mark(`cache.LISTENER_RESPONSE`, key);
554+
const done = mark(`cache.${action.type.replace(/(@@.+\/)/, '')}`, key);
545555
if (!draft.database) {
546556
set(draft, ['database'], {});
547557
set(draft, ['databaseOverrides'], {});
@@ -556,8 +566,11 @@ const initialize = (state, { action, key, path }) =>
556566
}
557567

558568
// set the query
559-
set(draft, [key], {
560-
ordered: action.payload.ordered.map(({ path, id }) => [path, id]),
569+
const ordered = (
570+
action.payload.ordered || selectDocuments(draft, action.meta)
571+
).map(({ path, id }) => [path, id]);
572+
set(draft, [action.meta.storeAs], {
573+
ordered,
561574
...action.meta,
562575
});
563576

@@ -582,13 +595,6 @@ const conclude = (state, { action, key, path }) =>
582595
return inUse;
583596
}, []);
584597

585-
// remove docs from database if unsed by other queries
586-
draft[key].ordered.forEach(([__, id]) => {
587-
if (!activeIds.includes(id)) {
588-
unset(draft, ['database', path, id]);
589-
}
590-
});
591-
592598
// remove query
593599
unset(draft, [key]);
594600

@@ -774,6 +780,7 @@ const mutation = (state, { action, key, path }) =>
774780
const HANDLERS = {
775781
[actionTypes.GET_SUCCESS]: initialize,
776782
[actionTypes.LISTENER_RESPONSE]: initialize,
783+
[actionTypes.SET_LISTENER]: initialize,
777784
[actionTypes.UNSET_LISTENER]: conclude,
778785
[actionTypes.DOCUMENT_ADDED]: modify,
779786
[actionTypes.DOCUMENT_MODIFIED]: modify,

test/unit/reducers/cacheReducer.spec.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -855,7 +855,7 @@ describe('cacheReducer', () => {
855855
});
856856

857857
describe('UNSET_LISTENER', () => {
858-
it('handles unset listener', () => {
858+
it('unset removes query but maintains in database cache', () => {
859859
const doc1 = { key1: 'value1', id: 'testDocId1' }; // initial doc
860860

861861
// Initial seed
@@ -887,7 +887,7 @@ describe('cacheReducer', () => {
887887
const pass2 = reducer(pass1, action2);
888888

889889
expect(pass2.cache.testStoreAs).to.eql(undefined);
890-
expect(pass2.cache.database[collection]).to.eql({});
890+
expect(pass2.cache.database[collection]).to.eql({ [doc1.id]: doc1 });
891891
});
892892

893893
it('handles a null payload.data', () => {

0 commit comments

Comments
 (0)