@@ -91,6 +91,16 @@ def inspect
91
91
"#<#{ self . class . name } response=#{ @response . inspect } >"
92
92
end
93
93
94
+ def tap_or_each ( obj_or_array )
95
+ if obj_or_array . is_a? ( Array )
96
+ obj_or_array . each do |item |
97
+ yield ( item , true )
98
+ end
99
+ else
100
+ yield ( obj_or_array , false )
101
+ end
102
+ end
103
+
94
104
# This _begins_ the execution. Some deferred work
95
105
# might be stored up in lazies.
96
106
# @return [void]
@@ -116,38 +126,27 @@ def run_eager
116
126
#
117
127
# Otherwise, `gathered_selections` is a hash of selections which can be
118
128
# directly evaluated and the results can be written right into the main response hash.
119
- if gathered_selections . is_a? ( Array )
120
- gathered_selections . each do | selections |
129
+ tap_or_each ( gathered_selections ) do | selections , is_selection_array |
130
+ if is_selection_array
121
131
selection_response = GraphQLResultHash . new
122
- @dataloader . append_job {
123
- set_all_interpreter_context ( query . root_value , nil , nil , path )
124
- resolve_with_directives ( object_proxy , selections . graphql_directives ) do
125
- evaluate_selections (
126
- path ,
127
- context . scoped_context ,
128
- object_proxy ,
129
- root_type ,
130
- root_op_type == "mutation" ,
131
- selections ,
132
- selection_response ,
133
- @response ,
134
- )
135
- end
136
- }
132
+ final_response = @response
133
+ else
134
+ selection_response = @response
135
+ final_response = nil
137
136
end
138
- else
137
+
139
138
@dataloader . append_job {
140
139
set_all_interpreter_context ( query . root_value , nil , nil , path )
141
- resolve_with_directives ( object_proxy , gathered_selections . graphql_directives ) do
140
+ resolve_with_directives ( object_proxy , selections . graphql_directives ) do
142
141
evaluate_selections (
143
142
path ,
144
143
context . scoped_context ,
145
144
object_proxy ,
146
145
root_type ,
147
146
root_op_type == "mutation" ,
148
- gathered_selections ,
149
- @response ,
150
- nil ,
147
+ selections ,
148
+ selection_response ,
149
+ final_response ,
151
150
)
152
151
end
153
152
}
@@ -599,53 +598,39 @@ def continue_field(path, value, owner_type, field, current_type, ast_node, next_
599
598
response_hash . graphql_result_name = result_name
600
599
set_result ( selection_result , result_name , response_hash )
601
600
gathered_selections = gather_selections ( continue_value , current_type , next_selections )
602
- # I wish I could figure out how to DRY this...
603
- # Basically, there are two possibilities:
601
+ # There are two possibilities for `gathered_selections`:
604
602
# 1. All selections of this object should be evaluated together (there are no runtime directives modifying execution).
605
603
# This case is handled below, and the result can be written right into the main `response_hash` above.
606
604
# In this case, `gathered_selections` is a hash of selections.
607
605
# 2. Some selections of this object have runtime directives that may or may not modify execution.
608
606
# That part of the selection is evaluated in an isolated way, writing into a sub-response object which is
609
607
# eventually merged into the final response. In this case, `gathered_selections` is an array of things to run in isolation.
610
608
# (Technically, it's possible that one of those entries _doesn't_ require isolation.)
611
- if gathered_selections . is_a? ( Array )
612
- gathered_selections . each do | selections |
609
+ tap_or_each ( gathered_selections ) do | selections , is_selection_array |
610
+ if is_selection_array
613
611
this_result = GraphQLResultHash . new
614
612
this_result . graphql_parent = selection_result
615
613
this_result . graphql_result_name = result_name
616
-
617
- set_all_interpreter_context ( continue_value , nil , nil , path ) # reset this mutable state
618
- resolve_with_directives ( continue_value , selections . graphql_directives ) do
619
- evaluate_selections (
620
- path ,
621
- context . scoped_context ,
622
- continue_value ,
623
- current_type ,
624
- false ,
625
- selections ,
626
- this_result ,
627
- response_hash ,
628
- )
629
- this_result
630
- end
614
+ final_result = response_hash
615
+ else
616
+ this_result = response_hash
617
+ final_result = nil
631
618
end
632
- else
633
619
set_all_interpreter_context ( continue_value , nil , nil , path ) # reset this mutable state
634
- resolve_with_directives ( continue_value , gathered_selections . graphql_directives ) do
620
+ resolve_with_directives ( continue_value , selections . graphql_directives ) do
635
621
evaluate_selections (
636
622
path ,
637
623
context . scoped_context ,
638
624
continue_value ,
639
625
current_type ,
640
626
false ,
641
- gathered_selections ,
642
- response_hash ,
643
- nil ,
627
+ selections ,
628
+ this_result ,
629
+ final_result ,
644
630
)
645
- response_hash
631
+ this_result
646
632
end
647
633
end
648
- response_hash
649
634
end
650
635
end
651
636
when "LIST"
0 commit comments