graphql-fragment_cache 1.9.1 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 120cfa12166d6db93a1aa709916694555f102d9c8ebeca53ccaba76182360c27
4
- data.tar.gz: ae01a7172430cbe6993ec0c8fabaa7024ab5786000869df42c95bd544f1e73f3
3
+ metadata.gz: 9c0987cb1e081b19356cfd389164150d7678c2fff2a479986f56e157ac485e79
4
+ data.tar.gz: 72cc6cf9a79c003be0c83dc60447840128ba1d8395e60171ce26a5eaf8190f2b
5
5
  SHA512:
6
- metadata.gz: 39ecafa948ec5b2a5c4954520e3d68709dafcaae53a4f12b5748ecedd7576f40e0e73705f7abdcb5e39f66e3e07506493547a3ed19a2e6d3f19246e53a6d5f23
7
- data.tar.gz: 9bb830762f4c155d70b068409fa8b1ddd49b34ebab0b4ce156d2e00a05127b1abd229dec4a61b029b6a60557254b6e0c650c7bc34b82bd713512acd6fcae4a63
6
+ metadata.gz: 78be339e321b1c76066e63960d615d85fc286531ba663eef4af3c62baee8b3d598867047cf1c52ca6085b7fca3cbd86ec0038718548e014aff5c8273740a3c9a
7
+ data.tar.gz: 005efd512fba6e4f91ba5aec08637ce058217f7c2e580ef4afa8c6323fef035a70c72a5abd74d418892f02b607b6e5fff288adfb9830ee9125985b852153775e
data/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 1.10.0 (2022-01-30)
6
+
7
+ - [PR#77](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/77) Drop Ruby 2.5 support, add Ruby 3.0 ([@DmitryTsepelev][])
8
+
5
9
  ## 1.9.1 (2021-11-28)
6
10
 
7
11
  - [PR#76](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/76) Freeze parser version ([@DmitryTsepelev][])
@@ -2,6 +2,6 @@
2
2
 
3
3
  module GraphQL
4
4
  module FragmentCache
5
- VERSION = "1.9.1"
5
+ VERSION = "1.10.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql-fragment_cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.1
4
+ version: 1.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - DmitryTsepelev
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-28 00:00:00.000000000 Z
11
+ date: 2022-01-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: graphql
@@ -190,10 +190,6 @@ files:
190
190
  - README.md
191
191
  - bin/console
192
192
  - bin/setup
193
- - lib/.rbnext/2.3/graphql/fragment_cache/cache_key_builder.rb
194
- - lib/.rbnext/2.3/graphql/fragment_cache/memory_store.rb
195
- - lib/.rbnext/2.7/graphql/fragment_cache/cache_key_builder.rb
196
- - lib/.rbnext/2.7/graphql/fragment_cache/ext/graphql_cache_key.rb
197
193
  - lib/graphql-fragment_cache.rb
198
194
  - lib/graphql/fragment_cache.rb
199
195
  - lib/graphql/fragment_cache/cache_key_builder.rb
@@ -219,7 +215,7 @@ metadata:
219
215
  homepage_uri: https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache
220
216
  source_code_uri: https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache
221
217
  changelog_uri: https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/CHANGELOG.md
222
- post_install_message:
218
+ post_install_message:
223
219
  rdoc_options: []
224
220
  require_paths:
225
221
  - lib
@@ -227,15 +223,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
227
223
  requirements:
228
224
  - - ">="
229
225
  - !ruby/object:Gem::Version
230
- version: '2.5'
226
+ version: '2.6'
231
227
  required_rubygems_version: !ruby/object:Gem::Requirement
232
228
  requirements:
233
229
  - - ">="
234
230
  - !ruby/object:Gem::Version
235
231
  version: '0'
236
232
  requirements: []
237
- rubygems_version: 3.2.31
238
- signing_key:
233
+ rubygems_version: 3.0.3.1
234
+ signing_key:
239
235
  specification_version: 4
240
236
  summary: Fragment cache for graphql-ruby
241
237
  test_files: []
@@ -1,198 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "json"
4
- require "digest"
5
-
6
- using RubyNext
7
-
8
- module GraphQL
9
- module FragmentCache
10
- using Ext
11
-
12
- using(Module.new {
13
- refine Array do
14
- def traverse_argument(argument)
15
- return argument unless argument.is_a?(GraphQL::Schema::InputObject)
16
-
17
- "{#{argument.map { |_1, _2| "#{_1}:#{traverse_argument(_2)}" }.sort.join(",")}}"
18
- end
19
-
20
- def to_selections_key
21
- map { |val|
22
- children = val.selections.empty? ? "" : "[#{val.selections.to_selections_key}]"
23
-
24
- field_name = val.field.name
25
- field_alias = val.ast_nodes.map(&:alias).join
26
- field_name = "#{field_alias}:#{field_name}" unless field_alias.empty?
27
-
28
- unless val.arguments.empty?
29
- args = val.arguments.map { |_1, _2| "#{_1}:#{traverse_argument(_2)}" }.sort.join(",")
30
- field_name += "(#{args})"
31
- end
32
-
33
- "#{field_name}#{children}"
34
- }.join(".")
35
- end
36
- end
37
-
38
- refine ::GraphQL::Language::Nodes::AbstractNode do
39
- def alias?(_)
40
- false
41
- end
42
- end
43
-
44
- refine ::GraphQL::Language::Nodes::Field do
45
- def alias?(val)
46
- self.alias == val
47
- end
48
- end
49
-
50
- refine ::GraphQL::Execution::Lookahead do
51
- def selection_with_alias(name, **kwargs)
52
- return selection(name, **kwargs) if selects?(name, **kwargs)
53
- alias_selection(name, **kwargs)
54
- end
55
-
56
- def alias_selection(name, selected_type: @selected_type, arguments: nil)
57
- return alias_selections[name] if alias_selections.key?(name)
58
-
59
- alias_node = lookup_alias_node(ast_nodes, name)
60
- return ::GraphQL::Execution::Lookahead::NULL_LOOKAHEAD unless alias_node
61
-
62
- next_field_name = alias_node.name
63
-
64
- # From https://github.com/rmosolgo/graphql-ruby/blob/1a9a20f3da629e63ea8e5ee8400be82218f9edc3/lib/graphql/execution/lookahead.rb#L91
65
- next_field_defn = get_class_based_field(selected_type, next_field_name)
66
-
67
- alias_selections[name] =
68
- if next_field_defn
69
- next_nodes = []
70
- arguments = @query.arguments_for(alias_node, next_field_defn)
71
- arguments = arguments.is_a?(::GraphQL::Execution::Interpreter::Arguments) ? arguments.keyword_arguments : arguments
72
- @ast_nodes.each do |ast_node|
73
- ast_node.selections.each do |selection|
74
- find_selected_nodes(selection, next_field_name, next_field_defn, arguments: arguments, matches: next_nodes)
75
- end
76
- end
77
-
78
- if next_nodes.any?
79
- ::GraphQL::Execution::Lookahead.new(query: @query, ast_nodes: next_nodes, field: next_field_defn, owner_type: selected_type)
80
- else
81
- ::GraphQL::Execution::Lookahead::NULL_LOOKAHEAD
82
- end
83
- else
84
- ::GraphQL::Execution::Lookahead::NULL_LOOKAHEAD
85
- end
86
- end
87
-
88
- def alias_selections
89
- return @alias_selections if defined?(@alias_selections)
90
- @alias_selections ||= {}
91
- end
92
-
93
- def lookup_alias_node(nodes, name)
94
- return if nodes.empty?
95
-
96
- nodes.find do |node|
97
- if node.is_a?(GraphQL::Language::Nodes::FragmentSpread)
98
- node = @query.fragments[node.name]
99
- raise("Invariant: Can't look ahead to nonexistent fragment #{node.name} (found: #{@query.fragments.keys})") unless node
100
- end
101
-
102
- return node if node.alias?(name)
103
- child = lookup_alias_node(node.children, name)
104
- return child if child
105
- end
106
- end
107
- end
108
- })
109
-
110
- # Builds cache key for fragment
111
- class CacheKeyBuilder
112
- using RubyNext
113
-
114
- class << self
115
- def call(**options)
116
- new(**options).build
117
- end
118
- end
119
-
120
- attr_reader :query, :path, :object, :schema
121
-
122
- def initialize(object: nil, query:, path:, **options)
123
- @object = object
124
- @query = query
125
- @schema = query.schema
126
- @path = path
127
- @options = options
128
- end
129
-
130
- def build
131
- [
132
- GraphQL::FragmentCache.namespace,
133
- implicit_cache_key,
134
- object_cache_key
135
- ].compact.join("/")
136
- end
137
-
138
- private
139
-
140
- def implicit_cache_key
141
- Digest::SHA1.hexdigest("#{schema_cache_key}/#{query_cache_key}")
142
- end
143
-
144
- def schema_cache_key
145
- @options.fetch(:schema_cache_key) { schema.schema_cache_key }
146
- end
147
-
148
- def query_cache_key
149
- @options.fetch(:query_cache_key) { "#{path_cache_key}[#{selections_cache_key}]" }
150
- end
151
-
152
- def selections_cache_key
153
- current_root =
154
- path.reduce(query.lookahead) { |lkhd, field_name|
155
- # Handle cached fields inside collections:
156
- next lkhd if field_name.is_a?(Integer)
157
-
158
- lkhd.selection_with_alias(field_name)
159
- }
160
-
161
- current_root.selections.to_selections_key
162
- end
163
-
164
- def path_cache_key
165
- @options.fetch(:path_cache_key) do
166
- lookahead = query.lookahead
167
-
168
- path.map { |field_name|
169
- # Handle cached fields inside collections:
170
- next field_name if field_name.is_a?(Integer)
171
-
172
- lookahead = lookahead.selection_with_alias(field_name)
173
- raise "Failed to look ahead the field: #{field_name}" if lookahead.is_a?(::GraphQL::Execution::Lookahead::NullLookahead)
174
-
175
- next lookahead.field.name if lookahead.arguments.empty?
176
-
177
- args = lookahead.arguments.map { |_1, _2| "#{_1}:#{traverse_argument(_2)}" }.sort.join(",")
178
- "#{lookahead.field.name}(#{args})"
179
- }.join("/")
180
- end
181
- end
182
-
183
- def traverse_argument(argument)
184
- return argument unless argument.is_a?(GraphQL::Schema::InputObject)
185
-
186
- "{#{argument.map { |_1, _2| "#{_1}:#{traverse_argument(_2)}" }.sort.join(",")}}"
187
- end
188
-
189
- def object_cache_key
190
- @options[:object_cache_key] || object_key(object)
191
- end
192
-
193
- def object_key(obj)
194
- ((!obj.nil?) || nil) && obj._graphql_cache_key
195
- end
196
- end
197
- end
198
- end
@@ -1,64 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- using RubyNext
4
-
5
- module GraphQL
6
- module FragmentCache
7
- # Memory adapter for storing cached fragments
8
- class MemoryStore
9
- using RubyNext
10
-
11
- class Entry < Struct.new(:value, :expires_at, keyword_init: true)
12
- def expired?
13
- expires_at && expires_at < Time.now
14
- end
15
- end
16
-
17
- attr_reader :default_expires_in
18
-
19
- def initialize(expires_in: nil, **other)
20
- raise ArgumentError, "Unsupported options: #{other.keys.join(",")}" unless other.empty?
21
-
22
- @default_expires_in = expires_in
23
- @storage = {}
24
- end
25
-
26
- def keys
27
- storage.keys
28
- end
29
-
30
- def exist?(key)
31
- storage.key?(key)
32
- end
33
-
34
- def read(key)
35
- key = key.to_s
36
- ((!storage[key].nil?) || nil) && storage[key].then do |entry|
37
- if entry.expired?
38
- delete(key)
39
- next
40
- end
41
- entry.value
42
- end
43
- end
44
-
45
- def write(key, value, expires_in: default_expires_in, **options)
46
- key = key.to_s
47
- @storage[key] = Entry.new(value: value, expires_at: expires_in ? Time.now + expires_in : nil)
48
- end
49
-
50
- def delete(key)
51
- key = key.to_s
52
- storage.delete(key)
53
- end
54
-
55
- def clear
56
- storage.clear
57
- end
58
-
59
- private
60
-
61
- attr_reader :storage
62
- end
63
- end
64
- end
@@ -1,198 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "json"
4
- require "digest"
5
-
6
- using RubyNext
7
-
8
- module GraphQL
9
- module FragmentCache
10
- using Ext
11
-
12
- using(Module.new {
13
- refine Array do
14
- def traverse_argument(argument)
15
- return argument unless argument.is_a?(GraphQL::Schema::InputObject)
16
-
17
- "{#{argument.map { |_1, _2| "#{_1}:#{traverse_argument(_2)}" }.sort.join(",")}}"
18
- end
19
-
20
- def to_selections_key
21
- map { |val|
22
- children = val.selections.empty? ? "" : "[#{val.selections.to_selections_key}]"
23
-
24
- field_name = val.field.name
25
- field_alias = val.ast_nodes.map(&:alias).join
26
- field_name = "#{field_alias}:#{field_name}" unless field_alias.empty?
27
-
28
- unless val.arguments.empty?
29
- args = val.arguments.map { |_1, _2| "#{_1}:#{traverse_argument(_2)}" }.sort.join(",")
30
- field_name += "(#{args})"
31
- end
32
-
33
- "#{field_name}#{children}"
34
- }.join(".")
35
- end
36
- end
37
-
38
- refine ::GraphQL::Language::Nodes::AbstractNode do
39
- def alias?(_)
40
- false
41
- end
42
- end
43
-
44
- refine ::GraphQL::Language::Nodes::Field do
45
- def alias?(val)
46
- self.alias == val
47
- end
48
- end
49
-
50
- refine ::GraphQL::Execution::Lookahead do
51
- def selection_with_alias(name, **kwargs)
52
- return selection(name, **kwargs) if selects?(name, **kwargs)
53
- alias_selection(name, **kwargs)
54
- end
55
-
56
- def alias_selection(name, selected_type: @selected_type, arguments: nil)
57
- return alias_selections[name] if alias_selections.key?(name)
58
-
59
- alias_node = lookup_alias_node(ast_nodes, name)
60
- return ::GraphQL::Execution::Lookahead::NULL_LOOKAHEAD unless alias_node
61
-
62
- next_field_name = alias_node.name
63
-
64
- # From https://github.com/rmosolgo/graphql-ruby/blob/1a9a20f3da629e63ea8e5ee8400be82218f9edc3/lib/graphql/execution/lookahead.rb#L91
65
- next_field_defn = get_class_based_field(selected_type, next_field_name)
66
-
67
- alias_selections[name] =
68
- if next_field_defn
69
- next_nodes = []
70
- arguments = @query.arguments_for(alias_node, next_field_defn)
71
- arguments = arguments.is_a?(::GraphQL::Execution::Interpreter::Arguments) ? arguments.keyword_arguments : arguments
72
- @ast_nodes.each do |ast_node|
73
- ast_node.selections.each do |selection|
74
- find_selected_nodes(selection, next_field_name, next_field_defn, arguments: arguments, matches: next_nodes)
75
- end
76
- end
77
-
78
- if next_nodes.any?
79
- ::GraphQL::Execution::Lookahead.new(query: @query, ast_nodes: next_nodes, field: next_field_defn, owner_type: selected_type)
80
- else
81
- ::GraphQL::Execution::Lookahead::NULL_LOOKAHEAD
82
- end
83
- else
84
- ::GraphQL::Execution::Lookahead::NULL_LOOKAHEAD
85
- end
86
- end
87
-
88
- def alias_selections
89
- return @alias_selections if defined?(@alias_selections)
90
- @alias_selections ||= {}
91
- end
92
-
93
- def lookup_alias_node(nodes, name)
94
- return if nodes.empty?
95
-
96
- nodes.find do |node|
97
- if node.is_a?(GraphQL::Language::Nodes::FragmentSpread)
98
- node = @query.fragments[node.name]
99
- raise("Invariant: Can't look ahead to nonexistent fragment #{node.name} (found: #{@query.fragments.keys})") unless node
100
- end
101
-
102
- return node if node.alias?(name)
103
- child = lookup_alias_node(node.children, name)
104
- return child if child
105
- end
106
- end
107
- end
108
- })
109
-
110
- # Builds cache key for fragment
111
- class CacheKeyBuilder
112
- using RubyNext
113
-
114
- class << self
115
- def call(**options)
116
- new(**options).build
117
- end
118
- end
119
-
120
- attr_reader :query, :path, :object, :schema
121
-
122
- def initialize(object: nil, query:, path:, **options)
123
- @object = object
124
- @query = query
125
- @schema = query.schema
126
- @path = path
127
- @options = options
128
- end
129
-
130
- def build
131
- [
132
- GraphQL::FragmentCache.namespace,
133
- implicit_cache_key,
134
- object_cache_key
135
- ].compact.join("/")
136
- end
137
-
138
- private
139
-
140
- def implicit_cache_key
141
- Digest::SHA1.hexdigest("#{schema_cache_key}/#{query_cache_key}")
142
- end
143
-
144
- def schema_cache_key
145
- @options.fetch(:schema_cache_key) { schema.schema_cache_key }
146
- end
147
-
148
- def query_cache_key
149
- @options.fetch(:query_cache_key) { "#{path_cache_key}[#{selections_cache_key}]" }
150
- end
151
-
152
- def selections_cache_key
153
- current_root =
154
- path.reduce(query.lookahead) { |lkhd, field_name|
155
- # Handle cached fields inside collections:
156
- next lkhd if field_name.is_a?(Integer)
157
-
158
- lkhd.selection_with_alias(field_name)
159
- }
160
-
161
- current_root.selections.to_selections_key
162
- end
163
-
164
- def path_cache_key
165
- @options.fetch(:path_cache_key) do
166
- lookahead = query.lookahead
167
-
168
- path.map { |field_name|
169
- # Handle cached fields inside collections:
170
- next field_name if field_name.is_a?(Integer)
171
-
172
- lookahead = lookahead.selection_with_alias(field_name)
173
- raise "Failed to look ahead the field: #{field_name}" if lookahead.is_a?(::GraphQL::Execution::Lookahead::NullLookahead)
174
-
175
- next lookahead.field.name if lookahead.arguments.empty?
176
-
177
- args = lookahead.arguments.map { |_1, _2| "#{_1}:#{traverse_argument(_2)}" }.sort.join(",")
178
- "#{lookahead.field.name}(#{args})"
179
- }.join("/")
180
- end
181
- end
182
-
183
- def traverse_argument(argument)
184
- return argument unless argument.is_a?(GraphQL::Schema::InputObject)
185
-
186
- "{#{argument.map { |_1, _2| "#{_1}:#{traverse_argument(_2)}" }.sort.join(",")}}"
187
- end
188
-
189
- def object_cache_key
190
- @options[:object_cache_key] || object_key(object)
191
- end
192
-
193
- def object_key(obj)
194
- obj&._graphql_cache_key
195
- end
196
- end
197
- end
198
- end
@@ -1,93 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module GraphQL
4
- module FragmentCache
5
- module Ext
6
- # Adds #_graphql_cache_key method to Object,
7
- # which just call #graphql_cache_key or #cache_key.
8
- #
9
- # For other core classes returns string representation.
10
- #
11
- # Raises ArgumentError otherwise.
12
- #
13
- # We use a refinement to avoid case/if statements for type checking
14
- refine Object do
15
- def _graphql_cache_key
16
- return graphql_cache_key if respond_to?(:graphql_cache_key)
17
- return cache_key if respond_to?(:cache_key)
18
- return to_a._graphql_cache_key if respond_to?(:to_a)
19
-
20
- to_s
21
- end
22
- end
23
-
24
- refine Array do
25
- def _graphql_cache_key
26
- map { |_1| _1._graphql_cache_key }.join("/")
27
- end
28
- end
29
-
30
- refine NilClass do
31
- def _graphql_cache_key
32
- ""
33
- end
34
- end
35
-
36
- refine TrueClass do
37
- def _graphql_cache_key
38
- "t"
39
- end
40
- end
41
-
42
- refine FalseClass do
43
- def _graphql_cache_key
44
- "f"
45
- end
46
- end
47
-
48
- refine String do
49
- def _graphql_cache_key
50
- self
51
- end
52
- end
53
-
54
- refine Symbol do
55
- def _graphql_cache_key
56
- to_s
57
- end
58
- end
59
-
60
- if RUBY_PLATFORM.match?(/java/i)
61
- refine Integer do
62
- def _graphql_cache_key
63
- to_s
64
- end
65
- end
66
-
67
- refine Float do
68
- def _graphql_cache_key
69
- to_s
70
- end
71
- end
72
- else
73
- refine Numeric do
74
- def _graphql_cache_key
75
- to_s
76
- end
77
- end
78
- end
79
-
80
- refine Time do
81
- def _graphql_cache_key
82
- to_s
83
- end
84
- end
85
-
86
- refine Module do
87
- def _graphql_cache_key
88
- name
89
- end
90
- end
91
- end
92
- end
93
- end