Skip to content

Commit

Permalink
Recursively apply deferred marker
Browse files Browse the repository at this point in the history
  • Loading branch information
kitten committed Apr 19, 2023
1 parent dac731b commit ea41be5
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 20 deletions.
16 changes: 14 additions & 2 deletions exchanges/graphcache/src/operations/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,13 @@ const readRoot = (
return input;
}

const iterate = makeSelectionIterator(entityKey, entityKey, select, ctx);
const iterate = makeSelectionIterator(
entityKey,
entityKey,
deferRef.current,
select,
ctx
);

let node: FieldNode | void;
let hasChanged = false;
Expand Down Expand Up @@ -330,7 +336,13 @@ const readSelection = (
}

const resolvers = store.resolvers[typename];
const iterate = makeSelectionIterator(typename, entityKey, select, ctx);
const iterate = makeSelectionIterator(
typename,
entityKey,
deferRef.current,
select,
ctx
);

let hasFields = false;
let hasPartials = false;
Expand Down
68 changes: 56 additions & 12 deletions exchanges/graphcache/src/operations/shared.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,13 @@ describe('makeSelectionIterator', () => {
}
`
);
const iterate = makeSelectionIterator('Query', 'Query', selection, ctx);
const iterate = makeSelectionIterator(
'Query',
'Query',
false,
selection,
ctx
);
const result: FieldNode[] = [];

let node: FieldNode | void;
Expand Down Expand Up @@ -78,7 +84,13 @@ describe('makeSelectionIterator', () => {
}
`);

const iterate = makeSelectionIterator('Query', 'Query', selection, ctx);
const iterate = makeSelectionIterator(
'Query',
'Query',
false,
selection,
ctx
);
const result: FieldNode[] = [];

let node: FieldNode | void;
Expand All @@ -102,7 +114,13 @@ describe('makeSelectionIterator', () => {
}
`);

const iterate = makeSelectionIterator('Query', 'Query', selection, ctx);
const iterate = makeSelectionIterator(
'Query',
'Query',
false,
selection,
ctx
);
const result: FieldNode[] = [];

let node: FieldNode | void;
Expand Down Expand Up @@ -181,16 +199,16 @@ describe('makeSelectionIterator', () => {
}
`);

const iterate = makeSelectionIterator('Query', 'Query', selection, ctx);
const result: FieldNode[] = [];
const deferred: boolean[] = [];

let node: FieldNode | void;
while ((node = iterate())) {
result.push(node);
deferred.push(deferRef.current);
}
const iterate = makeSelectionIterator(
'Query',
'Query',
false,
selection,
ctx
);

const deferred: boolean[] = [];
while (iterate()) deferred.push(deferRef.current);
expect(deferred).toEqual([
false, // a
true, // b
Expand All @@ -202,4 +220,30 @@ describe('makeSelectionIterator', () => {
false, // h
]);
});

it('applies the parent’s defer state if needed', () => {
const selection = selectionOfDocument(gql`
{
a
... @defer {
b
}
... {
c
}
}
`);

const iterate = makeSelectionIterator(
'Query',
'Query',
true,
selection,
ctx
);

const deferred: boolean[] = [];
while (iterate()) deferred.push(deferRef.current);
expect(deferred).toEqual([true, true, true]);
});
});
10 changes: 4 additions & 6 deletions exchanges/graphcache/src/operations/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,22 +158,20 @@ interface SelectionIterator {
export const makeSelectionIterator = (
typename: void | string,
entityKey: string,
defer: boolean,
selectionSet: SelectionSet,
ctx: Context
): SelectionIterator => {
let defer = false;
let child: SelectionIterator | void;
let index = 0;

return function next() {
let node: FieldNode | undefined;
while (child || index < selectionSet.length) {
node = undefined;
deferRef.current = false;
deferRef.current = defer;
if (child) {
node = child();
deferRef.current = deferRef.current || defer;
if (node) {
if ((node = child())) {
return node;
} else {
child = undefined;
Expand Down Expand Up @@ -202,10 +200,10 @@ export const makeSelectionIterator = (
if (isMatching) {
if (process.env.NODE_ENV !== 'production')
pushDebugNode(typename, fragment);
defer = isDeferred(select, ctx.variables);
child = makeSelectionIterator(
typename,
entityKey,
defer || isDeferred(select, ctx.variables),
getSelectionSet(fragment),
ctx
);
Expand Down
1 change: 1 addition & 0 deletions exchanges/graphcache/src/operations/write.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ const writeSelection = (
const iterate = makeSelectionIterator(
typename,
entityKey || typename,
deferRef.current,
select,
ctx
);
Expand Down

0 comments on commit ea41be5

Please sign in to comment.