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