feat: cache search results (#869)
This commit is contained in:
parent
6022ead87a
commit
1c8ff049c5
@ -2,6 +2,7 @@ import isEqual from 'lodash/isEqual';
|
|||||||
|
|
||||||
import { currentBackend } from '../backend';
|
import { currentBackend } from '../backend';
|
||||||
import {
|
import {
|
||||||
|
CLEAR_REQUESTS,
|
||||||
QUERY_FAILURE,
|
QUERY_FAILURE,
|
||||||
QUERY_REQUEST,
|
QUERY_REQUEST,
|
||||||
QUERY_SUCCESS,
|
QUERY_SUCCESS,
|
||||||
@ -13,7 +14,7 @@ import {
|
|||||||
|
|
||||||
import type { AnyAction } from 'redux';
|
import type { AnyAction } from 'redux';
|
||||||
import type { ThunkDispatch } from 'redux-thunk';
|
import type { ThunkDispatch } from 'redux-thunk';
|
||||||
import type { Entry, SearchQueryResponse } from '../interface';
|
import type { Entry, SearchQueryRequest, SearchQueryResponse } from '../interface';
|
||||||
import type { RootState } from '../store';
|
import type { RootState } from '../store';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -44,11 +45,12 @@ export function searchFailure(error: Error) {
|
|||||||
} as const;
|
} as const;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function querying(searchTerm: string) {
|
export function querying(searchTerm: string, request?: SearchQueryRequest) {
|
||||||
return {
|
return {
|
||||||
type: QUERY_REQUEST,
|
type: QUERY_REQUEST,
|
||||||
payload: {
|
payload: {
|
||||||
searchTerm,
|
searchTerm,
|
||||||
|
request,
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
}
|
}
|
||||||
@ -78,6 +80,10 @@ export function clearSearch() {
|
|||||||
return { type: SEARCH_CLEAR } as const;
|
return { type: SEARCH_CLEAR } as const;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function clearRequests() {
|
||||||
|
return { type: CLEAR_REQUESTS } as const;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Exported Thunk Action Creators
|
* Exported Thunk Action Creators
|
||||||
*/
|
*/
|
||||||
@ -180,4 +186,5 @@ export type SearchAction = ReturnType<
|
|||||||
| typeof querySuccess
|
| typeof querySuccess
|
||||||
| typeof queryFailure
|
| typeof queryFailure
|
||||||
| typeof clearSearch
|
| typeof clearSearch
|
||||||
|
| typeof clearRequests
|
||||||
>;
|
>;
|
||||||
|
@ -110,6 +110,7 @@ export const QUERY_SUCCESS = 'QUERY_SUCCESS';
|
|||||||
export const QUERY_FAILURE = 'QUERY_FAILURE';
|
export const QUERY_FAILURE = 'QUERY_FAILURE';
|
||||||
|
|
||||||
export const SEARCH_CLEAR = 'SEARCH_CLEAR';
|
export const SEARCH_CLEAR = 'SEARCH_CLEAR';
|
||||||
|
export const CLEAR_REQUESTS = 'CLEAR_REQUESTS';
|
||||||
|
|
||||||
// Status
|
// Status
|
||||||
export const STATUS_REQUEST = 'STATUS_REQUEST';
|
export const STATUS_REQUEST = 'STATUS_REQUEST';
|
||||||
|
@ -1037,6 +1037,12 @@ export interface SearchResponse {
|
|||||||
pagination: number;
|
pagination: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type SearchQueryRequest = {
|
||||||
|
id: string;
|
||||||
|
expires: Date;
|
||||||
|
queryResponse: Promise<SearchQueryResponse>;
|
||||||
|
};
|
||||||
|
|
||||||
export interface SearchQueryResponse {
|
export interface SearchQueryResponse {
|
||||||
hits: Entry[];
|
hits: Entry[];
|
||||||
query: string;
|
query: string;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
|
CLEAR_REQUESTS,
|
||||||
QUERY_FAILURE,
|
QUERY_FAILURE,
|
||||||
QUERY_REQUEST,
|
QUERY_REQUEST,
|
||||||
QUERY_SUCCESS,
|
QUERY_SUCCESS,
|
||||||
@ -9,6 +10,7 @@ import {
|
|||||||
} from '../constants';
|
} from '../constants';
|
||||||
|
|
||||||
import type { SearchAction } from '../actions/search';
|
import type { SearchAction } from '../actions/search';
|
||||||
|
import type { SearchQueryRequest } from '../interface';
|
||||||
|
|
||||||
export interface SearchState {
|
export interface SearchState {
|
||||||
isFetching: boolean;
|
isFetching: boolean;
|
||||||
@ -17,6 +19,7 @@ export interface SearchState {
|
|||||||
page: number;
|
page: number;
|
||||||
entryIds: { collection: string; slug: string }[];
|
entryIds: { collection: string; slug: string }[];
|
||||||
error: Error | undefined;
|
error: Error | undefined;
|
||||||
|
requests: SearchQueryRequest[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultState: SearchState = {
|
const defaultState: SearchState = {
|
||||||
@ -26,6 +29,7 @@ const defaultState: SearchState = {
|
|||||||
page: 0,
|
page: 0,
|
||||||
entryIds: [],
|
entryIds: [],
|
||||||
error: undefined,
|
error: undefined,
|
||||||
|
requests: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
const search = (state: SearchState = defaultState, action: SearchAction): SearchState => {
|
const search = (state: SearchState = defaultState, action: SearchAction): SearchState => {
|
||||||
@ -66,14 +70,26 @@ const search = (state: SearchState = defaultState, action: SearchAction): Search
|
|||||||
}
|
}
|
||||||
|
|
||||||
case QUERY_REQUEST: {
|
case QUERY_REQUEST: {
|
||||||
const { searchTerm } = action.payload;
|
const { searchTerm, request } = action.payload;
|
||||||
|
|
||||||
|
const requests = [...state.requests];
|
||||||
|
if (request) {
|
||||||
|
requests.push(request);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
isFetching: true,
|
isFetching: true,
|
||||||
term: searchTerm,
|
term: searchTerm,
|
||||||
|
requests,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case CLEAR_REQUESTS: {
|
||||||
|
state.requests = state.requests.filter(req => req.expires >= new Date());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case QUERY_SUCCESS: {
|
case QUERY_SUCCESS: {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user