@@ -109,13 +109,13 @@ export type ExecutionResult = {
109
109
} ;
110
110
111
111
/**
112
- * A partial result of GraphQL execution. `data` and `errors` as above.
113
- * "NP" = "Not Promise".
112
+ * A partial result of GraphQL execution. `data` and `errors` as above, but
113
+ * tuple to avoid allocating/destroying objects. "NP" = "Not Promise".
114
114
*/
115
- export type ExecutionPartialResultNP < T > = {
116
- errors ?: $ReadOnlyArray < GraphQLError > ,
117
- data ?: T | null ,
118
- } ;
115
+ export type ExecutionPartialResultNP < T > = [
116
+ T | null ,
117
+ $ReadOnlyArray < GraphQLError > | null ,
118
+ ] ;
119
119
120
120
/**
121
121
* A partial result of GraphQL execution. `data` and `errors` as above.
@@ -234,17 +234,17 @@ function executeImpl(
234
234
}
235
235
236
236
/**
237
- * Strip out `errors` if empty.
237
+ * Given a completed ExecutionPartialResult, build the { errors, data }
238
+ * response defined by the "Response" section of the GraphQL specification.
238
239
*/
239
240
function buildResponse ( result : ExecutionPartialResult < mixed > ) {
240
241
const promise = getPromise ( result ) ;
241
242
if ( promise ) {
242
243
return promise . then ( resolved => buildResponse ( resolved ) ) ;
243
244
}
244
- if ( result . data && ( ! result . errors || ! result . errors . length ) ) {
245
- return { data : result . data } ;
246
- }
247
- return result ;
245
+ return ! result [ 1 ] || result [ 1 ] . length === 0
246
+ ? { data : result [ 0 ] }
247
+ : { data : result [ 0 ] , errors : result [ 1 ] } ;
248
248
}
249
249
250
250
/**
@@ -413,14 +413,11 @@ function executeOperation(
413
413
: executeFields ( exeContext , type , rootValue , path , fields ) ;
414
414
const promise = getPromise ( result ) ;
415
415
if ( promise ) {
416
- return promise . then ( undefined , error => ( {
417
- data : null ,
418
- errors : [ error ] ,
419
- } ) ) ;
416
+ return promise . then ( undefined , error => [ null , [ error ] ] ) ;
420
417
}
421
418
return result ;
422
419
} catch (error) {
423
- return { data : null , errors : [ error ] } ;
420
+ return [ null , [ error ] ] ;
424
421
}
425
422
}
426
423
@@ -559,13 +556,13 @@ function mergeEPRs(
559
556
const values = keys . map ( name => eprMap [ name ] ) ;
560
557
return values . reduce (
561
558
( merged , value , i ) => {
562
- merged . data [ keys [ i ] ] = value . data ;
563
- if ( value . errors && value . errors . length ) {
564
- merged . errors . push ( ...value . errors ) ;
559
+ merged [ 0 ] [ keys [ i ] ] = value [ 0 ] ;
560
+ if ( value [ 1 ] && value [ 1 ] . length ) {
561
+ merged [ 1 ] . push ( ...value [ 1 ] ) ;
565
562
}
566
563
return merged ;
567
564
} ,
568
- { data : Object . create ( null ) , errors : [ ] } ,
565
+ [ Object . create ( null ) , [ ] ] ,
569
566
) ;
570
567
}
571
568
@@ -874,16 +871,13 @@ function completeValueCatchingError(
874
871
// the rejection error and resolve to null.
875
872
// Note: we don't rely on a `catch` method, but we do expect "thenable"
876
873
// to take a second callback for the error case.
877
- return promise . then ( undefined , error => ( {
878
- data : null ,
879
- errors : [ error ] ,
880
- } ) ) ;
874
+ return promise . then ( undefined , error => [ null , [ error ] ] ) ;
881
875
}
882
876
return completed ;
883
877
} catch ( error ) {
884
878
// If `completeValueWithLocatedError` returned abruptly (threw an error),
885
879
// log the error and return null.
886
- return { data : null , errors : [ error ] } ;
880
+ return [ null , [ error ] ] ;
887
881
}
888
882
}
889
883
@@ -981,7 +975,7 @@ function completeValue(
981
975
path ,
982
976
result ,
983
977
) ;
984
- if ( completed . data === null ) {
978
+ if ( completed [ 0 ] === null ) {
985
979
throw new Error (
986
980
`Cannot return null for non-nullable field ${ info . parentType . name } .${
987
981
info . fieldName
@@ -993,7 +987,7 @@ function completeValue(
993
987
994
988
// If result value is null-ish (null, undefined, or NaN) then return null.
995
989
if ( isNullish ( result ) ) {
996
- return { data : null } ;
990
+ return [ null , null ] ;
997
991
}
998
992
999
993
// If field type is List, complete each item in the list with the inner type
@@ -1011,7 +1005,7 @@ function completeValue(
1011
1005
// If field type is a leaf type, Scalar or Enum, serialize to a valid value,
1012
1006
// returning null if serialization is not possible.
1013
1007
if ( isLeafType ( returnType ) ) {
1014
- return { data : completeLeafValue ( returnType , result ) } ;
1008
+ return [ completeLeafValue ( returnType , result ) , null ] ;
1015
1009
}
1016
1010
1017
1011
// If field type is an abstract type, Interface or Union, determine the
@@ -1102,12 +1096,12 @@ function flattenEPRs(
1102
1096
const errors = [ ] ;
1103
1097
const data = [ ] ;
1104
1098
forEach ( ( eprs : any ) , item => {
1105
- data . push ( item . data ) ;
1106
- if ( item . errors && item . errors . length ) {
1107
- errors . push ( ...item . errors ) ;
1099
+ data . push ( item [ 0 ] ) ;
1100
+ if ( item [ 1 ] && item [ 1 ] . length ) {
1101
+ errors . push ( ...item [ 1 ] ) ;
1108
1102
}
1109
1103
} ) ;
1110
- return { data , errors } ;
1104
+ return [ data , errors . length ? errors : null ] ;
1111
1105
}
1112
1106
1113
1107
/**
0 commit comments