graphql-fragment_cache 1.9.1 → 1.12.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/CHANGELOG.md +11 -0
- data/README.md +1 -13
- data/lib/.rbnext/2.3/graphql/fragment_cache/cache_key_builder.rb +6 -1
- data/lib/.rbnext/2.7/graphql/fragment_cache/cache_key_builder.rb +6 -1
- data/lib/graphql/fragment_cache/cache_key_builder.rb +6 -1
- data/lib/graphql/fragment_cache/field_extension.rb +2 -0
- data/lib/graphql/fragment_cache/fragment.rb +26 -4
- data/lib/graphql/fragment_cache/object_helpers.rb +2 -8
- data/lib/graphql/fragment_cache/schema/lazy_cache_resolver.rb +41 -0
- data/lib/graphql/fragment_cache/schema/tracer.rb +1 -1
- data/lib/graphql/fragment_cache/version.rb +1 -1
- data/lib/graphql/fragment_cache.rb +6 -13
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb58b8735fa1b7a92dae359467252e366bf34da888f46ef98db0737db7b6dfc4
|
4
|
+
data.tar.gz: 037dd3a8c61ed1f359b50d6ae0e4ae7f169d825fb5c6da8cf0ee8968c6e1b9b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6eef1102518837f505b077f515b7a6e38a6e37993f072921193e30a2a877aec2e67899e8d256b23738cabda2bddf7a8e99967743c14b504afcedd389e2d23734
|
7
|
+
data.tar.gz: cb110783f67fb0674065fae17ff860e6c2a81a2fde04f5800634c689f2a1bcf01a54d5183e0ffbf5359d709a9b5493d967be39809abccf91fb5701b00eac7f7f
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 1.11.0 (2022-02-26)
|
6
|
+
|
7
|
+
- [PR#70](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/70), [PR#82](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/82) Add #read_multi for fragments ([@daukadolt][], [@frostmark][])
|
8
|
+
- [PR#79](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/79) Support graphql-ruby 2.0.0 ([@DmitryTsepelev][])
|
9
|
+
|
10
|
+
## 1.10.0 (2022-01-30)
|
11
|
+
|
12
|
+
- [PR#77](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/77) Drop Ruby 2.5 support, add Ruby 3.0 ([@DmitryTsepelev][])
|
13
|
+
|
5
14
|
## 1.9.1 (2021-11-28)
|
6
15
|
|
7
16
|
- [PR#76](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/76) Freeze parser version ([@DmitryTsepelev][])
|
@@ -120,3 +129,5 @@
|
|
120
129
|
[@bbugh]: https://github.com/bbugh
|
121
130
|
[@jeromedalbert]: https://github.com/jeromedalbert
|
122
131
|
[@mretzak]: https://github.com/mretzak
|
132
|
+
[@daukadolt]: https://github.com/daukadolt
|
133
|
+
[@frostmark]: https://github.com/frostmark
|
data/README.md
CHANGED
@@ -17,13 +17,10 @@ end
|
|
17
17
|
|
18
18
|
## Getting started
|
19
19
|
|
20
|
-
Add the gem to your Gemfile `gem 'graphql-fragment_cache'` and add the plugin to your schema class
|
20
|
+
Add the gem to your Gemfile `gem 'graphql-fragment_cache'` and add the plugin to your schema class:
|
21
21
|
|
22
22
|
```ruby
|
23
23
|
class GraphqSchema < GraphQL::Schema
|
24
|
-
use GraphQL::Execution::Interpreter
|
25
|
-
use GraphQL::Analysis::AST
|
26
|
-
|
27
24
|
use GraphQL::FragmentCache
|
28
25
|
|
29
26
|
query QueryType
|
@@ -69,15 +66,6 @@ class QueryType < BaseObject
|
|
69
66
|
end
|
70
67
|
```
|
71
68
|
|
72
|
-
If you use [connections](https://graphql-ruby.org/pagination/connection_concepts.html) and plan to cache them—please turn on [brand new](https://github.com/rmosolgo/graphql-ruby/blob/master/lib/graphql/pagination/connections.rb#L5) connections hierarchy in your schema:
|
73
|
-
|
74
|
-
```ruby
|
75
|
-
class GraphqSchema < GraphQL::Schema
|
76
|
-
# ...
|
77
|
-
use GraphQL::Pagination::Connections
|
78
|
-
end
|
79
|
-
```
|
80
|
-
|
81
69
|
## Cache key generation
|
82
70
|
|
83
71
|
Cache keys consist of the following parts: namespace, implicit key, and explicit key.
|
@@ -62,7 +62,12 @@ module GraphQL
|
|
62
62
|
next_field_name = alias_node.name
|
63
63
|
|
64
64
|
# From https://github.com/rmosolgo/graphql-ruby/blob/1a9a20f3da629e63ea8e5ee8400be82218f9edc3/lib/graphql/execution/lookahead.rb#L91
|
65
|
-
next_field_defn =
|
65
|
+
next_field_defn =
|
66
|
+
if GraphQL::FragmentCache.graphql_ruby_before_2_0?
|
67
|
+
get_class_based_field(selected_type, next_field_name)
|
68
|
+
else
|
69
|
+
@query.get_field(selected_type, next_field_name)
|
70
|
+
end
|
66
71
|
|
67
72
|
alias_selections[name] =
|
68
73
|
if next_field_defn
|
@@ -62,7 +62,12 @@ module GraphQL
|
|
62
62
|
next_field_name = alias_node.name
|
63
63
|
|
64
64
|
# From https://github.com/rmosolgo/graphql-ruby/blob/1a9a20f3da629e63ea8e5ee8400be82218f9edc3/lib/graphql/execution/lookahead.rb#L91
|
65
|
-
next_field_defn =
|
65
|
+
next_field_defn =
|
66
|
+
if GraphQL::FragmentCache.graphql_ruby_before_2_0?
|
67
|
+
get_class_based_field(selected_type, next_field_name)
|
68
|
+
else
|
69
|
+
@query.get_field(selected_type, next_field_name)
|
70
|
+
end
|
66
71
|
|
67
72
|
alias_selections[name] =
|
68
73
|
if next_field_defn
|
@@ -62,7 +62,12 @@ module GraphQL
|
|
62
62
|
next_field_name = alias_node.name
|
63
63
|
|
64
64
|
# From https://github.com/rmosolgo/graphql-ruby/blob/1a9a20f3da629e63ea8e5ee8400be82218f9edc3/lib/graphql/execution/lookahead.rb#L91
|
65
|
-
next_field_defn =
|
65
|
+
next_field_defn =
|
66
|
+
if GraphQL::FragmentCache.graphql_ruby_before_2_0?
|
67
|
+
get_class_based_field(selected_type, next_field_name)
|
68
|
+
else
|
69
|
+
@query.get_field(selected_type, next_field_name)
|
70
|
+
end
|
66
71
|
|
67
72
|
alias_selections[name] =
|
68
73
|
if next_field_defn
|
@@ -8,19 +8,41 @@ module GraphQL
|
|
8
8
|
|
9
9
|
# Represents a single fragment to cache
|
10
10
|
class Fragment
|
11
|
+
NIL_IN_CACHE = Object.new
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def read_multi(fragments)
|
15
|
+
unless FragmentCache.cache_store.respond_to?(:read_multi)
|
16
|
+
return fragments.map { |f| [f, f.read] }.to_h
|
17
|
+
end
|
18
|
+
|
19
|
+
fragments_to_cache_keys = fragments
|
20
|
+
.map { |f| [f, f.cache_key] }.to_h
|
21
|
+
|
22
|
+
cache_keys = fragments_to_cache_keys.values
|
23
|
+
|
24
|
+
cache_keys_to_values = FragmentCache.cache_store.read_multi(*cache_keys)
|
25
|
+
|
26
|
+
fetched_fragments_to_values = cache_keys_to_values
|
27
|
+
.map { |key, val| [fragments_to_cache_keys.key(key), val] }
|
28
|
+
.to_h
|
29
|
+
|
30
|
+
fetched_fragments_to_values
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
11
34
|
attr_reader :options, :path, :context
|
12
35
|
|
13
36
|
def initialize(context, **options)
|
14
37
|
@context = context
|
38
|
+
@keep_in_context = options.delete(:keep_in_context)
|
15
39
|
@options = options
|
16
40
|
@path = interpreter_context[:current_path]
|
17
41
|
end
|
18
42
|
|
19
|
-
|
20
|
-
|
21
|
-
def read(keep_in_context = false)
|
43
|
+
def read
|
22
44
|
return nil if context[:renew_cache] == true
|
23
|
-
return read_from_context { value_from_cache } if keep_in_context
|
45
|
+
return read_from_context { value_from_cache } if @keep_in_context
|
24
46
|
|
25
47
|
value_from_cache
|
26
48
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "graphql/fragment_cache/fragment"
|
4
|
+
require "graphql/fragment_cache/schema/lazy_cache_resolver"
|
4
5
|
|
5
6
|
module GraphQL
|
6
7
|
module FragmentCache
|
@@ -44,14 +45,7 @@ module GraphQL
|
|
44
45
|
|
45
46
|
fragment = Fragment.new(context_to_use, **options)
|
46
47
|
|
47
|
-
|
48
|
-
if (cached = fragment.read(keep_in_context))
|
49
|
-
return cached == Fragment::NIL_IN_CACHE ? nil : raw_value(cached)
|
50
|
-
end
|
51
|
-
|
52
|
-
(block_given? ? block.call : object_to_cache).tap do |resolved_value|
|
53
|
-
context_to_use.fragments << fragment
|
54
|
-
end
|
48
|
+
GraphQL::FragmentCache::Schema::LazyCacheResolver.new(fragment, context_to_use, object_to_cache, &block)
|
55
49
|
end
|
56
50
|
end
|
57
51
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "graphql/fragment_cache/fragment"
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module FragmentCache
|
5
|
+
module Schema
|
6
|
+
using Ext
|
7
|
+
class LazyCacheResolver
|
8
|
+
def initialize(fragment, query_ctx, object_to_cache, &block)
|
9
|
+
@fragment = fragment
|
10
|
+
@query_ctx = query_ctx
|
11
|
+
@object_to_cache = object_to_cache
|
12
|
+
@lazy_state = query_ctx[:lazy_cache_resolver_statez] ||= {
|
13
|
+
pending_fragments: Set.new,
|
14
|
+
resolved_fragments: {}
|
15
|
+
}
|
16
|
+
@block = block
|
17
|
+
|
18
|
+
@lazy_state[:pending_fragments] << @fragment
|
19
|
+
end
|
20
|
+
|
21
|
+
def resolve
|
22
|
+
unless @lazy_state[:resolved_fragments].key?(@fragment)
|
23
|
+
resolved_fragments = Fragment.read_multi(@lazy_state[:pending_fragments].to_a)
|
24
|
+
@lazy_state[:pending_fragments].clear
|
25
|
+
resolved_fragments.each { |key, value| @lazy_state[:resolved_fragments][key] = value }
|
26
|
+
end
|
27
|
+
|
28
|
+
cached = @lazy_state[:resolved_fragments][@fragment]
|
29
|
+
|
30
|
+
if cached
|
31
|
+
return cached == Fragment::NIL_IN_CACHE ? nil : GraphQL::Execution::Interpreter::RawValue.new(cached)
|
32
|
+
end
|
33
|
+
|
34
|
+
(@block ? @block.call : @object_to_cache).tap do |resolved_value|
|
35
|
+
@query_ctx.fragments << @fragment
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -23,7 +23,7 @@ module GraphQL
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def verify_connections!(context)
|
26
|
-
return if
|
26
|
+
return if context.schema.new_connections?
|
27
27
|
|
28
28
|
raise StandardError,
|
29
29
|
"GraphQL::Pagination::Connections should be enabled for connection caching"
|
@@ -11,6 +11,7 @@ require "graphql/fragment_cache/connections/patch"
|
|
11
11
|
require "graphql/fragment_cache/schema/patch"
|
12
12
|
require "graphql/fragment_cache/schema/tracer"
|
13
13
|
require "graphql/fragment_cache/schema/instrumentation"
|
14
|
+
require "graphql/fragment_cache/schema/lazy_cache_resolver"
|
14
15
|
|
15
16
|
require "graphql/fragment_cache/memory_store"
|
16
17
|
|
@@ -30,6 +31,7 @@ module GraphQL
|
|
30
31
|
schema_defn.tracer(Schema::Tracer)
|
31
32
|
schema_defn.instrument(:query, Schema::Instrumentation)
|
32
33
|
schema_defn.extend(Schema::Patch)
|
34
|
+
schema_defn.lazy_resolve(Schema::LazyCacheResolver, :resolve)
|
33
35
|
|
34
36
|
GraphQL::Pagination::Connections.prepend(Connections::Patch)
|
35
37
|
end
|
@@ -50,29 +52,20 @@ module GraphQL
|
|
50
52
|
@cache_store = store
|
51
53
|
end
|
52
54
|
|
53
|
-
def
|
54
|
-
Gem::Dependency.new("graphql", "
|
55
|
+
def graphql_ruby_before_2_0?
|
56
|
+
Gem::Dependency.new("graphql", "< 2.0.0").match?("graphql", GraphQL::VERSION)
|
55
57
|
end
|
56
58
|
|
57
59
|
private
|
58
60
|
|
59
61
|
def verify_interpreter_and_analysis!(schema_defn)
|
60
|
-
if
|
61
|
-
unless schema_defn.interpreter?
|
62
|
-
raise StandardError,
|
63
|
-
"GraphQL::Execution::Execute should not be enabled for fragment caching"
|
64
|
-
end
|
65
|
-
|
66
|
-
unless schema_defn.analysis_engine == GraphQL::Analysis::AST
|
67
|
-
raise StandardError,
|
68
|
-
"GraphQL::Analysis should not be enabled for fragment caching"
|
69
|
-
end
|
70
|
-
else
|
62
|
+
if graphql_ruby_before_2_0?
|
71
63
|
unless schema_defn.interpreter?
|
72
64
|
raise StandardError,
|
73
65
|
"GraphQL::Execution::Interpreter should be enabled for fragment caching"
|
74
66
|
end
|
75
67
|
|
68
|
+
puts "schema_defn.analysis_engine #{schema_defn.analysis_engine}"
|
76
69
|
unless schema_defn.analysis_engine == GraphQL::Analysis::AST
|
77
70
|
raise StandardError,
|
78
71
|
"GraphQL::Analysis::AST should be enabled for fragment caching"
|
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.
|
4
|
+
version: 1.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- DmitryTsepelev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-08-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.
|
19
|
+
version: 1.12.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.
|
26
|
+
version: 1.12.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: ruby-next
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -209,6 +209,7 @@ files:
|
|
209
209
|
- lib/graphql/fragment_cache/rails/cache_key_builder.rb
|
210
210
|
- lib/graphql/fragment_cache/railtie.rb
|
211
211
|
- lib/graphql/fragment_cache/schema/instrumentation.rb
|
212
|
+
- lib/graphql/fragment_cache/schema/lazy_cache_resolver.rb
|
212
213
|
- lib/graphql/fragment_cache/schema/patch.rb
|
213
214
|
- lib/graphql/fragment_cache/schema/tracer.rb
|
214
215
|
- lib/graphql/fragment_cache/version.rb
|
@@ -227,14 +228,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
227
228
|
requirements:
|
228
229
|
- - ">="
|
229
230
|
- !ruby/object:Gem::Version
|
230
|
-
version: '2.
|
231
|
+
version: '2.6'
|
231
232
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
232
233
|
requirements:
|
233
234
|
- - ">="
|
234
235
|
- !ruby/object:Gem::Version
|
235
236
|
version: '0'
|
236
237
|
requirements: []
|
237
|
-
rubygems_version: 3.
|
238
|
+
rubygems_version: 3.3.3
|
238
239
|
signing_key:
|
239
240
|
specification_version: 4
|
240
241
|
summary: Fragment cache for graphql-ruby
|