lib/graphql/batch/execution_strategy.rb in graphql-batch-0.1.0 vs lib/graphql/batch/execution_strategy.rb in graphql-batch-0.2.0
- old
+ new
@@ -1,57 +1,61 @@
module GraphQL::Batch
class ExecutionStrategy < GraphQL::Query::SerialExecution
- attr_reader :batched_queries
+ def execute(_, _, _)
+ as_promise(super).sync
+ ensure
+ GraphQL::Batch::Executor.current.clear
+ end
- def initialize
- @batched_queries = Hash.new{ |hash, key| hash[key] = [] }
+ private
+
+ def as_promise(result)
+ GraphQL::Batch::Promise.resolve(as_promise_unless_resolved(result))
end
- class OperationResolution < GraphQL::Query::SerialExecution::OperationResolution
- def result
- result = super
- until execution_strategy.batched_queries.empty?
- queries = execution_strategy.batched_queries.shift.last
- queries.first.class.execute(queries)
+ def as_promise_unless_resolved(result)
+ all_promises = []
+ each_promise(result) do |obj, key, promise|
+ obj[key] = nil
+ all_promises << promise.then do |value|
+ obj[key] = value
+ as_promise_unless_resolved(value)
end
- result
end
+ return result if all_promises.empty?
+ Promise.all(all_promises).then { result }
end
- class SelectionResolution < GraphQL::Query::SerialExecution::SelectionResolution
- def result
- result_hash = super
- result_hash.each do |key, value|
- if value.is_a?(FieldResolution)
- value.result_hash = result_hash
- end
+ def each_promise(obj, &block)
+ case obj
+ when Array
+ obj.each_with_index do |value, idx|
+ each_promise_in_entry(obj, idx, value, &block)
end
- result_hash
+ when Hash
+ obj.each do |key, value|
+ each_promise_in_entry(obj, key, value, &block)
+ end
end
end
- class FieldResolution < GraphQL::Query::SerialExecution::FieldResolution
- attr_accessor :result_hash
+ def each_promise_in_entry(obj, key, value, &block)
+ if value.is_a?(::Promise)
+ yield obj, key, value
+ else
+ each_promise(value, &block)
+ end
+ end
+ class FieldResolution < GraphQL::Query::SerialExecution::FieldResolution
def get_finished_value(raw_value)
- if raw_value.is_a?(QueryContainer)
- raw_value.query_listener = self
- register_queries(raw_value)
- self
+ if raw_value.is_a?(::Promise)
+ raw_value.then(->(result) { super(result) }, lambda do |error|
+ error.is_a?(GraphQL::ExecutionError) ? super(error) : raise(error)
+ end)
else
super
end
- end
-
- def register_queries(query_container)
- query_container.each_query do |query|
- execution_strategy.batched_queries[query.group_key] << query
- end
- end
-
- def query_completed(query)
- result_key = ast_node.alias || ast_node.name
- @result_hash[result_key] = get_finished_value(query.result)
end
end
end
end