Skip to content
This repository has been archived by the owner on Dec 30, 2022. It is now read-only.

Commit

Permalink
feat(infinite-hits): support cache
Browse files Browse the repository at this point in the history
  • Loading branch information
eunjae-lee committed Apr 27, 2020
1 parent b41bff2 commit e468e05
Showing 1 changed file with 55 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,29 @@ function getCurrentRefinement(props, searchState, context) {
return currentRefinement;
}

function getStateWithoutPage(state) {
const { page, ...rest } = state;
return rest;
}

function getInMemoryCache() {
let cachedHits = undefined;
let cachedState = undefined;
return {
read: ({ state }) => {
return isEqual(cachedState, getStateWithoutPage(state))
? cachedHits
: null;
},
write: ({ state, hits }) => {
cachedState = getStateWithoutPage(state);
cachedHits = hits;
},
};
}

function min(array) {}

/**
* InfiniteHits connector provides the logic to create connected
* components that will render an continuous list of results retrieved from
Expand All @@ -48,7 +71,6 @@ export default createConnector({
multiIndexContext: props.indexContextValue,
});

this._allResults = this._allResults || [];
this._prevState = this._prevState || {};

if (!results) {
Expand Down Expand Up @@ -76,32 +98,40 @@ export default createConnector({
results.queryID
);

const cache = props.cache || getInMemoryCache();
const stateForCache = results._state || {};
if (
this._firstReceivedPage === undefined ||
this._cachedHits === undefined ||
!isEqual(currentState, this._prevState)
) {
this._allResults = [...hitsWithPositionsAndQueryID];
this._firstReceivedPage = page;
this._lastReceivedPage = page;
} else if (this._lastReceivedPage < page) {
this._allResults = [...this._allResults, ...hitsWithPositionsAndQueryID];
this._lastReceivedPage = page;
} else if (this._firstReceivedPage > page) {
this._allResults = [...hitsWithPositionsAndQueryID, ...this._allResults];
this._firstReceivedPage = page;
this._cachedHits = cache.read({ state: stateForCache }) || {};
}
if (this._cachedHits[page] === undefined) {
this._cachedHits[page] = hitsWithPositionsAndQueryID;
cache.write({ state: stateForCache, hits: this._cachedHits });
}

this._prevState = currentState;

const hasPrevious = this._firstReceivedPage > 0;
/*
Math.min() and Math.max() returns Infinity or -Infinity when no argument is given.
But there is always something in this point because of `this._cachedHits[page]`.
*/
const firstReceivedPage = Math.min(...Object.keys(this._cachedHits));
const lastReceivedPage = Math.max(...Object.keys(this._cachedHits));
const flattenHits = Object.keys(this._cachedHits)
.sort()
.reduce((acc, _page) => {
return acc.concat(this._cachedHits[_page]);
}, []);

const hasPrevious = firstReceivedPage > 0;
const lastPageIndex = nbPages - 1;
const hasMore = page < lastPageIndex;
const refinePrevious = event =>
this.refine(event, this._firstReceivedPage - 1);
const refineNext = event => this.refine(event, this._lastReceivedPage + 1);
const hasMore = lastReceivedPage < lastPageIndex;
const refinePrevious = event => this.refine(event, firstReceivedPage - 1);
const refineNext = event => this.refine(event, lastReceivedPage + 1);

return {
hits: this._allResults,
hits: flattenHits,
hasPrevious,
hasMore,
refinePrevious,
Expand All @@ -120,8 +150,13 @@ export default createConnector({
},

refine(props, searchState, event, index) {
if (index === undefined && this._lastReceivedPage !== undefined) {
index = this._lastReceivedPage + 1;
const pages = Object.keys(this._cachedHits || {});
const lastReceivedPage =
pages.length === 0 ? undefined : Math.max(...pages);
// If there is no key in `this._cachedHits`,
// then `lastReceivedPage` should be `undefined`.
if (index === undefined && lastReceivedPage !== undefined) {
index = lastReceivedPage + 1;
} else if (index === undefined) {
index = getCurrentRefinement(props, searchState, {
ais: props.contextValue,
Expand Down

0 comments on commit e468e05

Please sign in to comment.