graphql-batch 0.4.3 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +23 -0
- data/.rubocop.yml +7 -2
- data/.rubocop_todo.yml +7 -0
- data/Gemfile +4 -1
- data/README.md +8 -18
- data/Rakefile +9 -5
- data/examples/active_storage_loader.rb +75 -0
- data/examples/association_loader.rb +2 -1
- data/examples/http_loader.rb +1 -0
- data/examples/record_loader.rb +1 -0
- data/examples/window_key_loader.rb +81 -0
- data/graphql-batch.gemspec +2 -5
- data/lib/graphql/batch/loader.rb +17 -3
- data/lib/graphql/batch/setup_multiplex.rb +2 -6
- data/lib/graphql/batch/version.rb +1 -1
- data/lib/graphql/batch.rb +9 -22
- metadata +8 -8
- data/.rubocop-https---shopify-github-io-ruby-style-guide-rubocop-yml +0 -1029
- data/.travis.yml +0 -11
- data/lib/graphql/batch/setup.rb +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b257f38787895a689caec957a242bef5fa56e02030b2ac499078a510820b8669
|
4
|
+
data.tar.gz: 9232d5995209ff370617a4f68f31cf936fd334ccd9eaad1cc449336d353a6535
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d8106c65d1842f98cbe1698e881e54c569d8452b684a6caea28b62a75cfde21a4b28fdbb6a61acb7a884dc6826a6209d05ddcdc6b3b7843ee6188202dfdfb638
|
7
|
+
data.tar.gz: 370418c233cc8fbf99734ba76eefd1c3d703a0bc40b249ed0dc8e24890a968fe45cf22ff8dc9d1a88c73dee5aa00971c4e3b0a5104048f9b5e3390bfced7a421
|
@@ -0,0 +1,23 @@
|
|
1
|
+
name: Tests
|
2
|
+
|
3
|
+
on:
|
4
|
+
- push
|
5
|
+
- pull_request
|
6
|
+
|
7
|
+
jobs:
|
8
|
+
test:
|
9
|
+
runs-on: ubuntu-latest
|
10
|
+
strategy:
|
11
|
+
fail-fast: false
|
12
|
+
matrix:
|
13
|
+
ruby: [2.4, 2.7, '3.0']
|
14
|
+
graphql_version: ['~> 1.10.0', '~> 1.13']
|
15
|
+
steps:
|
16
|
+
- uses: actions/checkout@v2
|
17
|
+
- uses: ruby/setup-ruby@v1
|
18
|
+
with:
|
19
|
+
bundler-cache: true
|
20
|
+
ruby-version: ${{ matrix.ruby }}
|
21
|
+
env:
|
22
|
+
GRAPHQL_VERSION: ${{ matrix.graphql_version }}
|
23
|
+
- run: bundle exec rake
|
data/.rubocop.yml
CHANGED
@@ -1,6 +1,11 @@
|
|
1
|
+
inherit_gem:
|
2
|
+
rubocop-shopify: rubocop.yml
|
3
|
+
|
1
4
|
inherit_from:
|
2
|
-
- https://shopify.github.io/ruby-style-guide/rubocop.yml
|
3
5
|
- .rubocop_todo.yml
|
4
6
|
|
5
7
|
AllCops:
|
6
|
-
|
8
|
+
SuggestExtensions: false
|
9
|
+
TargetRubyVersion: 2.7
|
10
|
+
Exclude:
|
11
|
+
- vendor/**/*
|
data/.rubocop_todo.yml
CHANGED
@@ -56,6 +56,13 @@ Layout/SpaceInsideParens:
|
|
56
56
|
Exclude:
|
57
57
|
- 'test/loader_test.rb'
|
58
58
|
|
59
|
+
# Offense count: 3
|
60
|
+
Lint/MissingSuper:
|
61
|
+
Exclude:
|
62
|
+
- 'test/executor_test.rb'
|
63
|
+
- 'test/loader_test.rb'
|
64
|
+
- 'test/support/loaders.rb'
|
65
|
+
|
59
66
|
# Offense count: 5
|
60
67
|
# Cop supports --auto-correct.
|
61
68
|
# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments.
|
data/Gemfile
CHANGED
@@ -3,4 +3,7 @@ source 'https://rubygems.org'
|
|
3
3
|
gemspec
|
4
4
|
|
5
5
|
gem 'graphql', ENV['GRAPHQL_VERSION'] if ENV['GRAPHQL_VERSION']
|
6
|
-
|
6
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.4.0')
|
7
|
+
gem 'rubocop', '~> 1.12.0', require: false
|
8
|
+
gem "rubocop-shopify", '~> 1.0.7', require: false
|
9
|
+
end
|
data/README.md
CHANGED
@@ -50,7 +50,7 @@ end
|
|
50
50
|
|
51
51
|
Use `GraphQL::Batch` as a plugin in your schema _after_ specifying the mutation
|
52
52
|
so that `GraphQL::Batch` can extend the mutation fields to clear the cache after
|
53
|
-
they are resolved
|
53
|
+
they are resolved.
|
54
54
|
|
55
55
|
```ruby
|
56
56
|
class MySchema < GraphQL::Schema
|
@@ -61,16 +61,6 @@ class MySchema < GraphQL::Schema
|
|
61
61
|
end
|
62
62
|
```
|
63
63
|
|
64
|
-
For pre `1.5.0` versions:
|
65
|
-
|
66
|
-
```ruby
|
67
|
-
MySchema = GraphQL::Schema.define do
|
68
|
-
query MyQueryType
|
69
|
-
|
70
|
-
GraphQL::Batch.use(self)
|
71
|
-
end
|
72
|
-
```
|
73
|
-
|
74
64
|
#### Field Usage
|
75
65
|
|
76
66
|
The loader class can be used from the resolver for a graphql field by calling `.for` with the grouping arguments to get a loader instance, then call `.load` on that instance with the key to load.
|
@@ -155,19 +145,19 @@ end
|
|
155
145
|
## Unit Testing
|
156
146
|
|
157
147
|
Your loaders can be tested outside of a GraphQL query by doing the
|
158
|
-
batch loads in a block passed to GraphQL::Batch.batch
|
148
|
+
batch loads in a block passed to `GraphQL::Batch.batch`. That method
|
159
149
|
will set up thread-local state to store the loaders, batch load any
|
160
150
|
promise returned from the block then clear the thread-local state
|
161
151
|
to avoid leaking state between tests.
|
162
152
|
|
163
153
|
```ruby
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
end
|
169
|
-
assert_equal product.title, title
|
154
|
+
def test_single_query
|
155
|
+
product = products(:snowboard)
|
156
|
+
title = GraphQL::Batch.batch do
|
157
|
+
RecordLoader.for(Product).load(product.id).then(&:title)
|
170
158
|
end
|
159
|
+
assert_equal product.title, title
|
160
|
+
end
|
171
161
|
```
|
172
162
|
|
173
163
|
## Development
|
data/Rakefile
CHANGED
@@ -7,9 +7,13 @@ Rake::TestTask.new(:test) do |t|
|
|
7
7
|
t.test_files = FileList['test/**/*_test.rb']
|
8
8
|
end
|
9
9
|
|
10
|
-
task :
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
task(default: :test)
|
11
|
+
|
12
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.4.0')
|
13
|
+
task :rubocop do
|
14
|
+
require 'rubocop/rake_task'
|
15
|
+
RuboCop::RakeTask.new
|
16
|
+
end
|
14
17
|
|
15
|
-
task(default:
|
18
|
+
task(default: :rubocop)
|
19
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
####
|
2
|
+
# This is a loader for has_one_attached and has_many_attached Active Storage attachments
|
3
|
+
# To load a variant for an attachment, 2 queries are required
|
4
|
+
# Using preloading via the includes method.
|
5
|
+
####
|
6
|
+
|
7
|
+
####
|
8
|
+
# The model with an attached image and many attached pictures
|
9
|
+
####
|
10
|
+
|
11
|
+
# class Event < ApplicationRecord
|
12
|
+
# has_one_attached :image
|
13
|
+
# has_many_attached :pictures
|
14
|
+
# end
|
15
|
+
|
16
|
+
####
|
17
|
+
# An example data type using the AttachmentLoader
|
18
|
+
####
|
19
|
+
|
20
|
+
# class Types::EventType < Types::BaseObject
|
21
|
+
# graphql_name 'Event'
|
22
|
+
#
|
23
|
+
# field :id, ID, null: false
|
24
|
+
# field :image, String, null: true
|
25
|
+
# field :pictures, String, null: true
|
26
|
+
#
|
27
|
+
# def image
|
28
|
+
# AttachmentLoader.for(:Event, :image).load(object.id).then do |image|
|
29
|
+
# Rails.application.routes.url_helpers.url_for(
|
30
|
+
# image.variant({ quality: 75 })
|
31
|
+
# )
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# def pictures
|
36
|
+
# AttachmentLoader.for(:Event, :pictures, association_type: :has_many_attached).load(object.id).then do |pictures|
|
37
|
+
# pictures.map do |picture|
|
38
|
+
# Rails.application.routes.url_helpers.url_for(
|
39
|
+
# picture.variant({ quality: 75 })
|
40
|
+
# )
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
# end
|
44
|
+
# end
|
45
|
+
module Loaders
|
46
|
+
class ActiveStorageLoader < GraphQL::Batch::Loader
|
47
|
+
attr_reader :record_type, :attachment_name, :association_type # should be has_one_attached or has_many_attached
|
48
|
+
|
49
|
+
def initialize(record_type, attachment_name, association_type: :has_one_attached)
|
50
|
+
super()
|
51
|
+
@record_type = record_type
|
52
|
+
@attachment_name = attachment_name
|
53
|
+
@association_type = association_type
|
54
|
+
end
|
55
|
+
|
56
|
+
def perform(record_ids)
|
57
|
+
# find records and fulfill promises
|
58
|
+
attachments = ActiveStorage::Attachment.includes(:blob).where(
|
59
|
+
record_type: record_type, record_id: record_ids, name: attachment_name
|
60
|
+
)
|
61
|
+
|
62
|
+
if @association_type == :has_one_attached
|
63
|
+
attachments.each do |attachment|
|
64
|
+
fulfill(attachment.record_id, attachment)
|
65
|
+
end
|
66
|
+
|
67
|
+
record_ids.each { |id| fulfill(id, nil) unless fulfilled?(id) }
|
68
|
+
else
|
69
|
+
record_ids.each do |record_id|
|
70
|
+
fulfill(record_id, attachments.select { |attachment| attachment.record_id == record_id })
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -5,6 +5,7 @@ class AssociationLoader < GraphQL::Batch::Loader
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def initialize(model, association_name)
|
8
|
+
super()
|
8
9
|
@model = model
|
9
10
|
@association_name = association_name
|
10
11
|
validate
|
@@ -35,7 +36,7 @@ class AssociationLoader < GraphQL::Batch::Loader
|
|
35
36
|
end
|
36
37
|
|
37
38
|
def preload_association(records)
|
38
|
-
::ActiveRecord::Associations::Preloader.new
|
39
|
+
::ActiveRecord::Associations::Preloader.new(records: records, associations: @association_name).call
|
39
40
|
end
|
40
41
|
|
41
42
|
def read_association(record)
|
data/examples/http_loader.rb
CHANGED
data/examples/record_loader.rb
CHANGED
@@ -0,0 +1,81 @@
|
|
1
|
+
####
|
2
|
+
# This is a has_many loader which takes advantage of Postgres'
|
3
|
+
# windowing functionality to load the first N records for
|
4
|
+
# a given relationship.
|
5
|
+
####
|
6
|
+
|
7
|
+
####
|
8
|
+
# An example data type using the WindowKeyLoader
|
9
|
+
####
|
10
|
+
|
11
|
+
# class Types::CategoryType < Types::BaseObject
|
12
|
+
# graphql_name 'Category'
|
13
|
+
|
14
|
+
# field :id, ID, null: false
|
15
|
+
# field :events, [Types::EventType], null: false do
|
16
|
+
# argument :first, Int, required: false, default_value: 5
|
17
|
+
# end
|
18
|
+
|
19
|
+
# def events(first:)
|
20
|
+
# WindowKeyLoader.for(
|
21
|
+
# Event,
|
22
|
+
# :category_id,
|
23
|
+
# limit: first, order_col: :start_time, order_dir: :desc
|
24
|
+
# ).load(object.id)
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
|
28
|
+
####
|
29
|
+
# The SQL that is produced
|
30
|
+
####
|
31
|
+
|
32
|
+
# SELECT
|
33
|
+
# "events".*
|
34
|
+
# FROM (
|
35
|
+
# SELECT
|
36
|
+
# "events".*,
|
37
|
+
# row_number() OVER (PARTITION BY category_id ORDER BY start_time DESC) AS rank
|
38
|
+
# FROM
|
39
|
+
# "events"
|
40
|
+
# WHERE
|
41
|
+
# "events"."category_id" IN(1, 2, 3, 4, 5)) AS events
|
42
|
+
# WHERE (rank <= 5)
|
43
|
+
|
44
|
+
class WindowKeyLoader < GraphQL::Batch::Loader
|
45
|
+
attr_reader :model, :foreign_key, :limit, :order_col, :order_dir
|
46
|
+
|
47
|
+
def initialize(model, foreign_key, limit:, order_col:, order_dir: :asc)
|
48
|
+
super()
|
49
|
+
@model = model
|
50
|
+
@foreign_key = foreign_key
|
51
|
+
@limit = limit
|
52
|
+
@order_col = order_col
|
53
|
+
@order_dir = order_dir
|
54
|
+
end
|
55
|
+
|
56
|
+
def perform(foreign_ids)
|
57
|
+
# build the sub-query, limiting results by foreign key at this point
|
58
|
+
# we don't want to execute this query but get its SQL to be used later
|
59
|
+
ranked_from =
|
60
|
+
model.select(
|
61
|
+
"*",
|
62
|
+
"row_number() OVER (
|
63
|
+
PARTITION BY #{foreign_key} ORDER BY #{order_col} #{order_dir}
|
64
|
+
) as rank"
|
65
|
+
).where(foreign_key => foreign_ids).to_sql
|
66
|
+
|
67
|
+
# use the sub-query from above to query records which have a rank
|
68
|
+
# value less than or equal to our limit
|
69
|
+
records =
|
70
|
+
model.from("(#{ranked_from}) as #{model.table_name}").where(
|
71
|
+
"rank <= #{limit}"
|
72
|
+
).to_a
|
73
|
+
|
74
|
+
# match records and fulfill promises
|
75
|
+
foreign_ids.each do |foreign_id|
|
76
|
+
matching_records =
|
77
|
+
records.select { |r| foreign_id == r.send(foreign_key) }
|
78
|
+
fulfill(foreign_id, matching_records)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/graphql-batch.gemspec
CHANGED
@@ -1,7 +1,4 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'graphql/batch/version'
|
1
|
+
require_relative 'lib/graphql/batch/version'
|
5
2
|
|
6
3
|
Gem::Specification.new do |spec|
|
7
4
|
spec.name = "graphql-batch"
|
@@ -20,7 +17,7 @@ Gem::Specification.new do |spec|
|
|
20
17
|
|
21
18
|
spec.metadata['allowed_push_host'] = "https://rubygems.org"
|
22
19
|
|
23
|
-
spec.add_runtime_dependency "graphql", ">= 1.
|
20
|
+
spec.add_runtime_dependency "graphql", ">= 1.10", "< 2"
|
24
21
|
spec.add_runtime_dependency "promise.rb", "~> 0.7.2"
|
25
22
|
|
26
23
|
spec.add_development_dependency "byebug" if RUBY_ENGINE == 'ruby'
|
data/lib/graphql/batch/loader.rb
CHANGED
@@ -34,7 +34,7 @@ module GraphQL::Batch
|
|
34
34
|
unless executor
|
35
35
|
raise GraphQL::Batch::NoExecutorError, 'Cannot create loader without'\
|
36
36
|
' an Executor. Wrap the call to `for` with `GraphQL::Batch.batch`'\
|
37
|
-
' or use `GraphQL::Batch::
|
37
|
+
' or use `GraphQL::Batch::SetupMultiplex` as a query instrumenter if'\
|
38
38
|
' using with `graphql-ruby`'
|
39
39
|
end
|
40
40
|
|
@@ -95,7 +95,15 @@ module GraphQL::Batch
|
|
95
95
|
|
96
96
|
# Returns true when the key has already been fulfilled, otherwise returns false
|
97
97
|
def fulfilled?(key)
|
98
|
-
promise_for(key)
|
98
|
+
promise = promise_for(key)
|
99
|
+
# When a promise is fulfilled through this class, it will either:
|
100
|
+
# become fulfilled, if fulfilled with a literal value
|
101
|
+
# become pending with a new source if fulfilled with a promise
|
102
|
+
# Either of these is acceptable, promise.rb will automatically re-wait
|
103
|
+
# on the new source promise as needed.
|
104
|
+
return true if promise.fulfilled?
|
105
|
+
|
106
|
+
promise.pending? && promise.source != self
|
99
107
|
end
|
100
108
|
|
101
109
|
# Must override to load the keys and call #fulfill for each key
|
@@ -140,7 +148,13 @@ module GraphQL::Batch
|
|
140
148
|
|
141
149
|
def check_for_broken_promises(load_keys)
|
142
150
|
load_keys.each do |key|
|
143
|
-
|
151
|
+
promise = promise_for(key)
|
152
|
+
# When a promise is fulfilled through this class, it will either:
|
153
|
+
# become not pending, if fulfilled with a literal value
|
154
|
+
# become pending with a new source if fulfilled with a promise
|
155
|
+
# Either of these is acceptable, promise.rb will automatically re-wait
|
156
|
+
# on the new source promise as needed.
|
157
|
+
next unless promise.pending? && promise.source == self
|
144
158
|
|
145
159
|
reject(key, ::Promise::BrokenError.new("#{self.class} didn't fulfill promise for key #{key.inspect}"))
|
146
160
|
end
|
@@ -6,15 +6,11 @@ module GraphQL::Batch
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def before_multiplex(multiplex)
|
9
|
-
|
9
|
+
GraphQL::Batch::Executor.start_batch(@executor_class)
|
10
10
|
end
|
11
11
|
|
12
12
|
def after_multiplex(multiplex)
|
13
|
-
|
14
|
-
end
|
15
|
-
|
16
|
-
def instrument(type, field)
|
17
|
-
Setup.instrument_field(@schema, type, field)
|
13
|
+
GraphQL::Batch::Executor.end_batch
|
18
14
|
end
|
19
15
|
end
|
20
16
|
end
|
data/lib/graphql/batch.rb
CHANGED
@@ -16,29 +16,17 @@ module GraphQL
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def self.use(schema_defn, executor_class: GraphQL::Batch::Executor)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
if
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
(schema.mutation.is_a?(Class) || schema.mutation.metadata[:type_class])
|
28
|
-
require_relative "batch/mutation_field_extension"
|
29
|
-
schema.mutation.fields.each do |name, f|
|
30
|
-
field = f.respond_to?(:type_class) ? f.type_class : f.metadata[:type_class]
|
31
|
-
field.extension(GraphQL::Batch::MutationFieldExtension)
|
32
|
-
end
|
33
|
-
else
|
34
|
-
schema_defn.instrument(:field, instrumentation)
|
35
|
-
end
|
19
|
+
instrumentation = GraphQL::Batch::SetupMultiplex.new(schema_defn, executor_class: executor_class)
|
20
|
+
schema_defn.instrument(:multiplex, instrumentation)
|
21
|
+
|
22
|
+
if schema_defn.mutation
|
23
|
+
require_relative "batch/mutation_field_extension"
|
24
|
+
|
25
|
+
schema_defn.mutation.fields.each do |name, field|
|
26
|
+
field.extension(GraphQL::Batch::MutationFieldExtension)
|
36
27
|
end
|
37
|
-
else
|
38
|
-
instrumentation = GraphQL::Batch::Setup.new(schema, executor_class: executor_class)
|
39
|
-
schema_defn.instrument(:query, instrumentation)
|
40
|
-
schema_defn.instrument(:field, instrumentation)
|
41
28
|
end
|
29
|
+
|
42
30
|
schema_defn.lazy_resolve(::Promise, :sync)
|
43
31
|
end
|
44
32
|
end
|
@@ -47,5 +35,4 @@ end
|
|
47
35
|
require_relative "batch/version"
|
48
36
|
require_relative "batch/loader"
|
49
37
|
require_relative "batch/executor"
|
50
|
-
require_relative "batch/setup"
|
51
38
|
require_relative "batch/setup_multiplex"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql-batch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dylan Thacker-Smith
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|
@@ -16,7 +16,7 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.10'
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: '2'
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: '1.
|
29
|
+
version: '1.10'
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '2'
|
@@ -93,11 +93,10 @@ executables: []
|
|
93
93
|
extensions: []
|
94
94
|
extra_rdoc_files: []
|
95
95
|
files:
|
96
|
+
- ".github/workflows/ci.yml"
|
96
97
|
- ".gitignore"
|
97
|
-
- ".rubocop-https---shopify-github-io-ruby-style-guide-rubocop-yml"
|
98
98
|
- ".rubocop.yml"
|
99
99
|
- ".rubocop_todo.yml"
|
100
|
-
- ".travis.yml"
|
101
100
|
- CONTRIBUTING.md
|
102
101
|
- Gemfile
|
103
102
|
- LICENSE.txt
|
@@ -105,15 +104,16 @@ files:
|
|
105
104
|
- Rakefile
|
106
105
|
- bin/console
|
107
106
|
- bin/setup
|
107
|
+
- examples/active_storage_loader.rb
|
108
108
|
- examples/association_loader.rb
|
109
109
|
- examples/http_loader.rb
|
110
110
|
- examples/record_loader.rb
|
111
|
+
- examples/window_key_loader.rb
|
111
112
|
- graphql-batch.gemspec
|
112
113
|
- lib/graphql/batch.rb
|
113
114
|
- lib/graphql/batch/executor.rb
|
114
115
|
- lib/graphql/batch/loader.rb
|
115
116
|
- lib/graphql/batch/mutation_field_extension.rb
|
116
|
-
- lib/graphql/batch/setup.rb
|
117
117
|
- lib/graphql/batch/setup_multiplex.rb
|
118
118
|
- lib/graphql/batch/version.rb
|
119
119
|
homepage: https://github.com/Shopify/graphql-batch
|
@@ -136,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
136
|
- !ruby/object:Gem::Version
|
137
137
|
version: '0'
|
138
138
|
requirements: []
|
139
|
-
rubygems_version: 3.
|
139
|
+
rubygems_version: 3.2.20
|
140
140
|
signing_key:
|
141
141
|
specification_version: 4
|
142
142
|
summary: A query batching executor for the graphql gem
|