Skip to content
This repository has been archived by the owner on Jul 6, 2020. It is now read-only.

Commit

Permalink
Fix relayPagination helper to serve correct partial results (#101)
Browse files Browse the repository at this point in the history
* Refactor relayPagination to not check entityKey

* Add additional partial logic to relayPagination
  • Loading branch information
kitten authored Sep 30, 2019
1 parent aafce3e commit acc0b96
Showing 1 changed file with 35 additions and 14 deletions.
49 changes: 35 additions & 14 deletions src/extras/relayPagination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,21 @@ export interface PaginationParams {
}

interface PageInfo {
__typename: string;
endCursor: null | string;
startCursor: null | string;
hasNextPage: boolean;
hasPreviousPage: boolean;
}

interface Page {
__typename: string;
edges: NullArray<string>;
pageInfo: PageInfo;
}

const defaultPageInfo: PageInfo = {
__typename: 'PageInfo',
endCursor: null,
startCursor: null,
hasNextPage: false,
Expand Down Expand Up @@ -56,23 +59,28 @@ const getPage = (cache: Cache, linkKey: string): Page | null => {
const link = ensureKey(cache.resolveValueOrLink(linkKey));
if (!link) return null;

const typename = cache.resolve(link, '__typename') as string;
const edges = cache.resolve(link, 'edges') as NullArray<string>;
if (
!Array.isArray(edges) ||
!edges.every(x => x === null || typeof x === 'string')
) {
if (typeof typename !== 'string' || !Array.isArray(edges)) {
return null;
}

const page: Page = { edges, pageInfo: defaultPageInfo };
const page: Page = {
__typename: typename,
edges,
pageInfo: defaultPageInfo,
};

const pageInfoKey = cache.resolve(link, 'pageInfo');
if (typeof pageInfoKey === 'string') {
const pageInfoType = ensureKey(cache.resolve(pageInfoKey, '__typename'));
const endCursor = ensureKey(cache.resolve(pageInfoKey, 'endCursor'));
const startCursor = ensureKey(cache.resolve(pageInfoKey, 'startCursor'));
const hasNextPage = cache.resolve(pageInfoKey, 'hasNextPage');
const hasPreviousPage = cache.resolve(pageInfoKey, 'hasPreviousPage');

const pageInfo: PageInfo = (page.pageInfo = {
__typename: typeof pageInfoType === 'string' ? pageInfoType : 'PageInfo',
hasNextPage: typeof hasNextPage === 'boolean' ? hasNextPage : !!endCursor,
hasPreviousPage:
typeof hasPreviousPage === 'boolean' ? hasPreviousPage : !!startCursor,
Expand Down Expand Up @@ -113,14 +121,7 @@ export const relayPagination = (params: PaginationParams = {}): Resolver => {
return undefined;
}

const typename = cache.resolve(entityKey, '__typename');

const pageInfoKey = ensureKey(cache.resolve(entityKey, 'pageInfo'));
const pageInfoTypename = cache.resolve(pageInfoKey, '__typename');
if (typeof typename !== 'string' || typeof pageInfoTypename !== 'string') {
return undefined;
}

let typename = '';
let startEdges: NullArray<string> = [];
let endEdges: NullArray<string> = [];
let pageInfo: PageInfo = { ...defaultPageInfo };
Expand All @@ -145,6 +146,26 @@ export const relayPagination = (params: PaginationParams = {}): Resolver => {
startEdges = concatEdges(cache, startEdges, page.edges);
pageInfo = page.pageInfo;
}

if (page.pageInfo.__typename !== pageInfo.__typename)
pageInfo.__typename = page.pageInfo.__typename;
if (typename !== page.__typename) typename = page.__typename;
}

if (
typeof typename !== 'string' ||
startEdges.length + endEdges.length === 0
) {
return undefined;
}

const hasCurrentPage = !!cache.resolve(entityKey, '__typename');
if (!hasCurrentPage) {
if ((info as any).schemaPredicates === undefined) {
return undefined;
} else {
info.partial = true;
}
}

return {
Expand All @@ -154,7 +175,7 @@ export const relayPagination = (params: PaginationParams = {}): Resolver => {
? concatEdges(cache, startEdges, endEdges)
: concatEdges(cache, endEdges, startEdges),
pageInfo: {
__typename: pageInfoTypename,
__typename: pageInfo.__typename,
endCursor: pageInfo.endCursor,
startCursor: pageInfo.startCursor,
hasNextPage: pageInfo.hasNextPage,
Expand Down

0 comments on commit acc0b96

Please sign in to comment.