Skip to content

Commit

Permalink
Add custom merge function option
Browse files Browse the repository at this point in the history
  • Loading branch information
orbiteleven committed Jun 28, 2022
1 parent 7f6075a commit 98fc0c3
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 16 deletions.
1 change: 1 addition & 0 deletions packages/lib/search/use-acter-search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export interface UseActerSearchQueryResults
}

type UseActerSearchOptions = UsePaginationQueryOptions<
Acter,
ActerSearchData,
SearchVariables
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
GetPaginatedResultsReducer,
PaginatedResultsActionKind,
PaginatedResultsState,
ResultsType,
StateResultsType,
} from './types'

describe('paginatedResultsReducer', () => {
Expand Down Expand Up @@ -134,7 +134,7 @@ describe('paginatedResultsReducer', () => {
results: OrderedMap({
1: { id: 1 },
2: { id: 2 },
}) as ResultsType,
}) as StateResultsType,
},
{
type: PaginatedResultsActionKind.NEW_RESULTS,
Expand All @@ -156,7 +156,7 @@ describe('paginatedResultsReducer', () => {
results: OrderedMap({
1: { id: 1 },
2: { id: 2 },
}) as ResultsType,
}) as StateResultsType,
},
{
type: PaginatedResultsActionKind.NEW_RESULTS,
Expand All @@ -172,6 +172,40 @@ describe('paginatedResultsReducer', () => {
})
})

describe('resultsMergeFn', () => {
it('should allow for different merge strategies', () => {
const result = getPaginatedResultsReducer<
{ id: number; foo: string },
unknown,
unknown
>({
resultsMergeFn: (state, item) =>
state.set(item.id.toString(), {
...item,
foo: 'bar'.repeat(item.id),
}),
})
reducer = result[0]
const newResults = [{ id: 1 }, { id: 2 }, { id: 3 }]
const state = reducer(
{
...defaultState,
results: OrderedMap() as StateResultsType,
},
{
type: PaginatedResultsActionKind.NEW_RESULTS,
payload: { results: newResults },
}
)

expect(state.results.toList().toArray()).toStrictEqual([
{ id: 1, foo: 'bar' },
{ id: 2, foo: 'barbar' },
{ id: 3, foo: 'barbarbar' },
])
})
})

describe('loadMore', () => {
it('should return if there are no results to load more from', () => {
const state = reducer(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@ export const getPaginatedResultsReducer = <
TType extends WithId,
TData,
TVariables
>(
{ pageSize }: GetPaginatedResultsReducerProps = {
pageSize: 20,
}
): GetPaginatedResultsReducerResult<TType, TData, TVariables> => {
>({
pageSize = 20,
resultsMergeFn = (map, item) => map.set(item.id.toString(), item),
}: GetPaginatedResultsReducerProps<TType> = {}): GetPaginatedResultsReducerResult<
TType,
TData,
TVariables
> => {
type ReducerState = PaginatedResultsState<TType, TData, TVariables>

const defaultPagination: Pagination = {
Expand Down Expand Up @@ -57,7 +60,7 @@ export const getPaginatedResultsReducer = <
const sliceEnd = hasMore ? -1 : undefined
const nextResultsPage = results.slice(0, sliceEnd)
const newResults = nextResultsPage.reduce(
(map, item) => map.set(item.id.toString(), item),
resultsMergeFn,
state.results
)
return {
Expand Down
23 changes: 18 additions & 5 deletions packages/lib/urql/use-paginated-query/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ export interface Pagination {
take: number
}

export type ResultsType<TType = unknown> = OrderedMap<string | number, TType>
export type StateResultsType<TType = unknown> = OrderedMap<
string | number,
TType
>
export interface PaginatedResultsState<TType, TData, TVariables>
extends UseQueryState<TData, TVariables> {
results: ResultsType<TType>
results: StateResultsType<TType>
fetching: boolean
hasMore: boolean
pagination: Pagination
Expand All @@ -36,8 +39,14 @@ export interface PaginatedResultsAction<TType> {
payload?: PaginatedResultsActionPayload<TType>
}

export interface GetPaginatedResultsReducerProps {
export type ResultsMergeFn<TType = unknown> = (
state: StateResultsType<TType>,
results: TType
) => StateResultsType<TType>

export interface GetPaginatedResultsReducerProps<TType = unknown> {
pageSize?: number
resultsMergeFn?: ResultsMergeFn<TType>
}

export type GetPaginatedResultsReducer<TType, TData, TVariables> = Reducer<
Expand Down Expand Up @@ -67,7 +76,7 @@ export type VariablesWithPagination<TVariables> = TVariables & Pagination

export interface UsePaginatedState<TType = any, TData = any, TVariables = any>
extends UseQueryState<TData, TVariables> {
results: ResultsType<TType>
results: StateResultsType<TType>
fetching: boolean
hasMore: boolean
pagination: Pagination
Expand All @@ -80,7 +89,7 @@ export type UsePaginatedResponse<TType, TData, TVariables> = [
UsePaginatedState<TType, TData, TVariables>,
refetch<TVariables>
]
export interface UsePaginationQueryOptions<TData, TVariables>
export interface UsePaginationQueryOptions<TType, TData, TVariables>
extends UseQueryArgs<TVariables, TData> {
/**
* The GraphQL query
Expand All @@ -102,6 +111,10 @@ export interface UsePaginationQueryOptions<TData, TVariables>
* Pagination options
*/
pagination?: Pagination
/**
* Merge function to use for new results
*/
resultsMergeFn?: ResultsMergeFn<TType>
}

export type WithId = {
Expand Down
5 changes: 3 additions & 2 deletions packages/lib/urql/use-paginated-query/use-paginated-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ import {
} from './types'

export const usePaginatedQuery = <TType extends WithId, TData, TVariables>(
options: UsePaginationQueryOptions<TData, TVariables>
options: UsePaginationQueryOptions<TType, TData, TVariables>
): UsePaginatedResponse<TType, TData, TVariables> => {
const { query, dataKey, variables, pageSize = 10 } = options
const { query, dataKey, variables, pageSize = 10, resultsMergeFn } = options

const [paginatedResultsReducer, { defaultState }] =
getPaginatedResultsReducer<TType, TData, TVariables>({
pageSize,
resultsMergeFn,
})
const [state, dispatch] = useReducer(paginatedResultsReducer, defaultState)

Expand Down

0 comments on commit 98fc0c3

Please sign in to comment.