diff --git a/packages/core/src/actions/search.ts b/packages/core/src/actions/search.ts index e1aa88d5..e5b607b1 100644 --- a/packages/core/src/actions/search.ts +++ b/packages/core/src/actions/search.ts @@ -2,6 +2,7 @@ import isEqual from 'lodash/isEqual'; import { currentBackend } from '../backend'; import { + CLEAR_REQUESTS, QUERY_FAILURE, QUERY_REQUEST, QUERY_SUCCESS, @@ -13,7 +14,7 @@ import { import type { AnyAction } from 'redux'; import type { ThunkDispatch } from 'redux-thunk'; -import type { Entry, SearchQueryResponse } from '../interface'; +import type { Entry, SearchQueryRequest, SearchQueryResponse } from '../interface'; import type { RootState } from '../store'; /* @@ -44,11 +45,12 @@ export function searchFailure(error: Error) { } as const; } -export function querying(searchTerm: string) { +export function querying(searchTerm: string, request?: SearchQueryRequest) { return { type: QUERY_REQUEST, payload: { searchTerm, + request, }, } as const; } @@ -78,6 +80,10 @@ export function clearSearch() { return { type: SEARCH_CLEAR } as const; } +export function clearRequests() { + return { type: CLEAR_REQUESTS } as const; +} + /* * Exported Thunk Action Creators */ @@ -180,4 +186,5 @@ export type SearchAction = ReturnType< | typeof querySuccess | typeof queryFailure | typeof clearSearch + | typeof clearRequests >; diff --git a/packages/core/src/constants.ts b/packages/core/src/constants.ts index 65785bc3..aed3631c 100644 --- a/packages/core/src/constants.ts +++ b/packages/core/src/constants.ts @@ -110,6 +110,7 @@ export const QUERY_SUCCESS = 'QUERY_SUCCESS'; export const QUERY_FAILURE = 'QUERY_FAILURE'; export const SEARCH_CLEAR = 'SEARCH_CLEAR'; +export const CLEAR_REQUESTS = 'CLEAR_REQUESTS'; // Status export const STATUS_REQUEST = 'STATUS_REQUEST'; diff --git a/packages/core/src/interface.ts b/packages/core/src/interface.ts index 9d143ccf..b427489a 100644 --- a/packages/core/src/interface.ts +++ b/packages/core/src/interface.ts @@ -1037,6 +1037,12 @@ export interface SearchResponse { pagination: number; } +export type SearchQueryRequest = { + id: string; + expires: Date; + queryResponse: Promise; +}; + export interface SearchQueryResponse { hits: Entry[]; query: string; diff --git a/packages/core/src/reducers/search.ts b/packages/core/src/reducers/search.ts index e0e91332..d9bb5feb 100644 --- a/packages/core/src/reducers/search.ts +++ b/packages/core/src/reducers/search.ts @@ -1,4 +1,5 @@ import { + CLEAR_REQUESTS, QUERY_FAILURE, QUERY_REQUEST, QUERY_SUCCESS, @@ -9,6 +10,7 @@ import { } from '../constants'; import type { SearchAction } from '../actions/search'; +import type { SearchQueryRequest } from '../interface'; export interface SearchState { isFetching: boolean; @@ -17,6 +19,7 @@ export interface SearchState { page: number; entryIds: { collection: string; slug: string }[]; error: Error | undefined; + requests: SearchQueryRequest[]; } const defaultState: SearchState = { @@ -26,6 +29,7 @@ const defaultState: SearchState = { page: 0, entryIds: [], error: undefined, + requests: [], }; const search = (state: SearchState = defaultState, action: SearchAction): SearchState => { @@ -66,14 +70,26 @@ const search = (state: SearchState = defaultState, action: SearchAction): Search } case QUERY_REQUEST: { - const { searchTerm } = action.payload; + const { searchTerm, request } = action.payload; + + const requests = [...state.requests]; + if (request) { + requests.push(request); + } + return { ...state, isFetching: true, term: searchTerm, + requests, }; } + case CLEAR_REQUESTS: { + state.requests = state.requests.filter(req => req.expires >= new Date()); + break; + } + case QUERY_SUCCESS: { return { ...state,