Skip to content

Commit

Permalink
expose all of the execution environment to resolvers
Browse files Browse the repository at this point in the history
presumably we should do this
  • Loading branch information
yaacovCR committed Feb 6, 2023
1 parent b057818 commit 3db08b5
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 59 deletions.
22 changes: 16 additions & 6 deletions src/execution/__tests__/defer-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ describe('Execute: defer directive', () => {
incremental: [
{
data: {
id: '1',
name: 'Luke',
},
path: ['hero'],
Expand Down Expand Up @@ -409,7 +410,9 @@ describe('Execute: defer directive', () => {
{
incremental: [
{
data: {},
data: {
name: 'Luke',
},
path: ['hero'],
},
],
Expand Down Expand Up @@ -444,7 +447,9 @@ describe('Execute: defer directive', () => {
{
incremental: [
{
data: {},
data: {
name: 'Luke',
},
path: ['hero'],
},
],
Expand Down Expand Up @@ -522,7 +527,7 @@ describe('Execute: defer directive', () => {
]);
});

it('Can deduplicate leaf fields present in the initial payload', async () => {
it('Does not deduplicate leaf fields present in the initial payload', async () => {
const document = parse(`
query {
hero {
Expand Down Expand Up @@ -580,7 +585,9 @@ describe('Execute: defer directive', () => {
},
},
anotherNestedObject: {
deeperObject: {},
deeperObject: {
foo: 'foo',
},
},
},
path: ['hero'],
Expand All @@ -591,7 +598,7 @@ describe('Execute: defer directive', () => {
]);
});

it('Can deduplicate fields with deferred fragments at multiple levels', async () => {
it('Does not deduplicate fields with deferred fragments at multiple levels', async () => {
const document = parse(`
query {
hero {
Expand Down Expand Up @@ -642,6 +649,7 @@ describe('Execute: defer directive', () => {
incremental: [
{
data: {
foo: 'foo',
bar: 'bar',
baz: 'baz',
bak: 'bak',
Expand All @@ -651,6 +659,7 @@ describe('Execute: defer directive', () => {
{
data: {
deeperObject: {
foo: 'foo',
bar: 'bar',
baz: 'baz',
},
Expand All @@ -661,6 +670,7 @@ describe('Execute: defer directive', () => {
data: {
nestedObject: {
deeperObject: {
foo: 'foo',
bar: 'bar',
},
},
Expand Down Expand Up @@ -732,7 +742,7 @@ describe('Execute: defer directive', () => {
]);
});

it('can deduplicate fields with deferred fragments in different branches at multiple non-overlapping levels', async () => {
it('Can deduplicate fields with deferred fragments in different branches at multiple non-overlapping levels', async () => {
const document = parse(`
query {
a {
Expand Down
8 changes: 5 additions & 3 deletions src/execution/__tests__/executor-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,8 @@ describe('Execute: Handles basic execution tasks', () => {

expect(resolvedInfo).to.have.all.keys(
'fieldName',
'fieldNodes',
'fieldGroup',
'deferDepth',
'returnType',
'parentType',
'path',
Expand All @@ -238,9 +239,10 @@ describe('Execute: Handles basic execution tasks', () => {
operation,
});

const field = operation.selectionSet.selections[0];
const fieldNode = operation.selectionSet.selections[0];
expect(resolvedInfo).to.deep.include({
fieldNodes: [field],
fieldGroup: [{ fieldNode, depth: 0, deferDepth: undefined }],
deferDepth: undefined,
variableValues: { var: 'abc' },
});

Expand Down
68 changes: 19 additions & 49 deletions src/execution/execute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ import type {
GraphQLTypeResolver,
} from '../type/definition.js';
import {
getNamedType,
isAbstractType,
isLeafType,
isListType,
Expand Down Expand Up @@ -631,26 +630,19 @@ function executeFieldsSerially(
(results, [responseName, fieldGroup]) => {
const fieldPath = exeContext.addPath(path, responseName, parentType.name);

const fieldName = fieldGroup[0].fieldNode.name.value;
const fieldDef = exeContext.schema.getField(parentType, fieldName);
if (!fieldDef) {
return results;
}

const returnType = fieldDef.type;

if (!shouldExecute(fieldGroup, returnType)) {
if (!shouldExecute(fieldGroup)) {
return results;
}
const result = executeField(
exeContext,
parentType,
fieldDef,
returnType,
sourceValue,
fieldGroup,
fieldPath,
);
if (result === undefined) {
return results;
}
if (isPromise(result)) {
return result.then((resolvedResult) => {
results[responseName] = resolvedResult;
Expand All @@ -666,25 +658,11 @@ function executeFieldsSerially(

function shouldExecute(
fieldGroup: FieldGroup,
returnType: GraphQLOutputType,
deferDepth?: number | undefined,
): boolean {
if (deferDepth === undefined || !isLeafType(getNamedType(returnType))) {
return fieldGroup.some(
({ deferDepth: fieldDeferDepth }) => fieldDeferDepth === deferDepth,
);
}

let hasDepth = false;
for (const { deferDepth: fieldDeferDepth } of fieldGroup) {
if (fieldDeferDepth === undefined) {
return false;
}
if (fieldDeferDepth === deferDepth) {
hasDepth = true;
}
}
return hasDepth;
return fieldGroup.some(
({ deferDepth: fieldDeferDepth }) => fieldDeferDepth === deferDepth,
);
}

/**
Expand All @@ -706,22 +684,10 @@ function executeFields(
for (const [responseName, fieldGroup] of groupedFieldSet) {
const fieldPath = exeContext.addPath(path, responseName, parentType.name);

const fieldName = fieldGroup[0].fieldNode.name.value;
const fieldDef = exeContext.schema.getField(parentType, fieldName);
if (!fieldDef) {
continue;
}

const returnType = fieldDef.type;

if (
shouldExecute(fieldGroup, returnType, asyncPayloadRecord?.deferDepth)
) {
if (shouldExecute(fieldGroup, asyncPayloadRecord?.deferDepth)) {
const result = executeField(
exeContext,
parentType,
fieldDef,
returnType,
sourceValue,
fieldGroup,
fieldPath,
Expand Down Expand Up @@ -769,15 +735,19 @@ function toNodes(fieldGroup: FieldGroup): ReadonlyArray<FieldNode> {
function executeField(
exeContext: ExecutionContext,
parentType: GraphQLObjectType,
fieldDef: GraphQLField<unknown, unknown>,
returnType: GraphQLOutputType,
source: unknown,
fieldGroup: FieldGroup,
path: Path,
asyncPayloadRecord?: AsyncPayloadRecord,
): PromiseOrValue<unknown> {
const errors = asyncPayloadRecord?.errors ?? exeContext.errors;
const fieldName = fieldGroup[0].fieldNode.name.value;
const fieldDef = exeContext.schema.getField(parentType, fieldName);
if (!fieldDef) {
return;
}

const returnType = fieldDef.type;
const resolveFn = fieldDef.resolve ?? exeContext.fieldResolver;

const info = buildResolveInfo(
Expand All @@ -786,6 +756,7 @@ function executeField(
fieldGroup,
parentType,
path,
asyncPayloadRecord,
);

// Get the resolve function, regardless of if its result is normal or abrupt (error).
Expand Down Expand Up @@ -865,12 +836,14 @@ export function buildResolveInfo(
fieldGroup: FieldGroup,
parentType: GraphQLObjectType,
path: Path,
asyncPayloadRecord?: AsyncPayloadRecord | undefined,
): GraphQLResolveInfo {
// The resolve function's optional fourth argument is a collection of
// information about the current execution state.
return {
fieldName: fieldDef.name,
fieldNodes: toNodes(fieldGroup),
fieldGroup,
deferDepth: asyncPayloadRecord?.deferDepth,
returnType: fieldDef.type,
parentType,
path,
Expand Down Expand Up @@ -1222,7 +1195,6 @@ function completeListValue(
// This is specified as a simple map, however we're optimizing the path
// where the list contains no Promises by avoiding creating another Promise.
let containsPromise = false;
const deferDepth = asyncPayloadRecord?.deferDepth;
let previousAsyncPayloadRecord = asyncPayloadRecord;
const completedResults: Array<unknown> = [];
let index = 0;
Expand All @@ -1244,7 +1216,6 @@ function completeListValue(
fieldGroup,
info,
itemType,
deferDepth,
previousAsyncPayloadRecord,
);
index++;
Expand Down Expand Up @@ -1923,11 +1894,10 @@ function executeStreamField(
fieldGroup: FieldGroup,
info: GraphQLResolveInfo,
itemType: GraphQLOutputType,
deferDepth: number | undefined,
parentContext?: AsyncPayloadRecord,
): AsyncPayloadRecord {
const asyncPayloadRecord = new StreamRecord({
deferDepth,
deferDepth: parentContext?.deferDepth,
path: itemPath,
parentContext,
exeContext,
Expand Down
7 changes: 6 additions & 1 deletion src/type/definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -890,7 +890,12 @@ export type GraphQLFieldResolver<

export interface GraphQLResolveInfo {
readonly fieldName: string;
readonly fieldNodes: ReadonlyArray<FieldNode>;
readonly fieldGroup: ReadonlyArray<{
fieldNode: FieldNode;
depth: number;
deferDepth: number | undefined;
}>;
readonly deferDepth: number | undefined;
readonly returnType: GraphQLOutputType;
readonly parentType: GraphQLObjectType;
readonly path: Path;
Expand Down

0 comments on commit 3db08b5

Please sign in to comment.