graphql-fragment_cache 0.1.3 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: da4850c60d1cba6fda41b4bba97680063b53ed9c7b8bf3e5727697891dce3908
4
- data.tar.gz: a1388572f4941b2db7090732b1e6548eed19cf364e8e67e92298e08b36a78ecf
3
+ metadata.gz: 96ef4de68daa875700330eed182cbbfeffb9c4dfff34dafd3661fc3513e06fc6
4
+ data.tar.gz: f24010337c683b12498c8c1cd949bb4ba43cb97dae80d9f617b0694a78329fdf
5
5
  SHA512:
6
- metadata.gz: 64b1d740c5fb423fd8d3118e57cbf45021415fd4907b3e3539dd1970545e265a7dabefba08e1d8611fd5827e8364398da699c4f3a2aceeea46bd0bab6ac7edca
7
- data.tar.gz: a1d8f8b808d1609cc97dc4ac83b5975e6c631b3fc6b41e68cbd49dc9469ee41139c24c370aa93908d79351d148f050c99b67a80452e31d9761812f52f2e4911c
6
+ metadata.gz: b5d84c411a488bac34c2e0c2237c3dcc7b51e44bd60195560ba81a8ee2cab6fd8d888f8946a103225b5dd14dc3202da4167a09901ad89264dee0bb3b34633fbd
7
+ data.tar.gz: 03bfa7468e8199ca87d81bcd8839f9dab0a7c6b4764538757727ad20d641c30da380af9b55a5496ef7ab77dafd444b2a8a39bd44d983d6e8eb53c0c63821f88f
@@ -2,6 +2,27 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 1.0.0 (2020-06-13)
6
+
7
+ - [PR#24](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/24) Add nil caching. **BREAKING CHANGE**: custom cache stores must also implement `#exist?(key)` method ([@DmitryTsepelev][])
8
+
9
+ ## 0.1.7 (2020-06-02)
10
+
11
+ - [PR#23](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/23) Avoid extra queries after restoring connection from cache ([@DmitryTsepelev][])
12
+
13
+ ## 0.1.6 (2020-05-30)
14
+
15
+ - [PR#22](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/22) Properly cache entites inside collections ([@DmitryTsepelev][])
16
+
17
+ ## 0.1.5 (2020-04-28)
18
+
19
+ - [PR#19](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/19) Add connections support ([@DmitryTsepelev][])
20
+ - [PR#18](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/18) Support aliases in cache key generation ([@palkan][], [@DmitryTsepelev][])
21
+
22
+ ## 0.1.4 (2020-04-25)
23
+
24
+ - Fix railtie to set up null store for tests ([@DmitryTsepelev][])
25
+
5
26
  ## 0.1.3 (2020-04-24)
6
27
 
7
28
  - [PR#17](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/17) Properly build cache keys based on input arguments ([@DmitryTsepelev][])
data/README.md CHANGED
@@ -61,6 +61,15 @@ class QueryType < BaseObject
61
61
  end
62
62
  ```
63
63
 
64
+ 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:
65
+
66
+ ```ruby
67
+ class GraphqSchema < GraphQL::Schema
68
+ # ...
69
+ use GraphQL::Pagination::Connections
70
+ end
71
+ ```
72
+
64
73
  ## Cache key generation
65
74
 
66
75
  Cache keys consist of implicit and explicit (provided by user) parts.
@@ -243,7 +252,7 @@ Rails.application.configure do |config|
243
252
  end
244
253
  ```
245
254
 
246
- ⚠️ Cache store must implement `#read(key)` and `#write(key, value, **options)` methods.
255
+ ⚠️ Cache store must implement `#read(key)`, `#write(key, value, **options)` and `#exist?(key)` methods.
247
256
 
248
257
  The gem provides only in-memory store out-of-the-box (`GraphQL::FragmentCache::MemoryStore`). It's used by default.
249
258
 
@@ -266,10 +275,6 @@ class QueryType < BaseObject
266
275
  end
267
276
  ```
268
277
 
269
- ## Limitations
270
-
271
- - [Field aliases](https://spec.graphql.org/June2018/#sec-Field-Alias) are not currently supported (take a look at the failing spec [here](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/7))
272
-
273
278
  ## Credits
274
279
 
275
280
  Based on the original [gist](https://gist.github.com/palkan/faad9f6ff1db16fcdb1c071ec50e4190) by [@palkan](https://github.com/palkan) and [@ssnickolay](https://github.com/ssnickolay).
@@ -18,6 +18,71 @@ module GraphQL
18
18
  }.join(".")
19
19
  end
20
20
  end
21
+
22
+ refine ::GraphQL::Language::Nodes::AbstractNode do
23
+ def alias?(_)
24
+ false
25
+ end
26
+ end
27
+
28
+ refine ::GraphQL::Language::Nodes::Field do
29
+ def alias?(val)
30
+ self.alias == val
31
+ end
32
+ end
33
+
34
+ refine ::GraphQL::Execution::Lookahead do
35
+ def selection_with_alias(name, **kwargs)
36
+ return selection(name, **kwargs) if selects?(name, **kwargs)
37
+ alias_selection(name, **kwargs)
38
+ end
39
+
40
+ def alias_selection(name, selected_type: @selected_type, arguments: nil)
41
+ return alias_selections[name] if alias_selections.key?(name)
42
+
43
+ alias_node = lookup_alias_node(ast_nodes, name)
44
+ return ::GraphQL::Execution::Lookahead::NULL_LOOKAHEAD unless alias_node
45
+
46
+ next_field_name = alias_node.name
47
+
48
+ # From https://github.com/rmosolgo/graphql-ruby/blob/1a9a20f3da629e63ea8e5ee8400be82218f9edc3/lib/graphql/execution/lookahead.rb#L91
49
+ next_field_defn = get_class_based_field(selected_type, next_field_name)
50
+
51
+ alias_selections[name] =
52
+ if next_field_defn
53
+ next_nodes = []
54
+ arguments = @query.arguments_for(alias_node, next_field_defn)
55
+ arguments = arguments.is_a?(::GraphQL::Execution::Interpreter::Arguments) ? arguments.keyword_arguments : arguments
56
+ @ast_nodes.each do |ast_node|
57
+ ast_node.selections.each do |selection|
58
+ find_selected_nodes(selection, next_field_name, next_field_defn, arguments: arguments, matches: next_nodes)
59
+ end
60
+ end
61
+
62
+ if next_nodes.any?
63
+ ::GraphQL::Execution::Lookahead.new(query: @query, ast_nodes: next_nodes, field: next_field_defn, owner_type: selected_type)
64
+ else
65
+ ::GraphQL::Execution::Lookahead::NULL_LOOKAHEAD
66
+ end
67
+ else
68
+ ::GraphQL::Execution::Lookahead::NULL_LOOKAHEAD
69
+ end
70
+ end
71
+
72
+ def alias_selections
73
+ return @alias_selections if defined?(@alias_selections)
74
+ @alias_selections ||= {}
75
+ end
76
+
77
+ def lookup_alias_node(nodes, name)
78
+ return if nodes.empty?
79
+ nodes.find do |node|
80
+ return node if node.alias?(name)
81
+ child = lookup_alias_node(node.children, name)
82
+ return child if child
83
+ end
84
+ end
85
+ end
21
86
  })
22
87
 
23
88
  # Builds cache key for fragment
@@ -59,7 +124,12 @@ module GraphQL
59
124
 
60
125
  def selections_cache_key
61
126
  current_root =
62
- path.reduce(query.lookahead) { |lkhd, name| lkhd.selection(name) }
127
+ path.reduce(query.lookahead) { |lkhd, field_name|
128
+ # Handle cached fields inside collections:
129
+ next lkhd if field_name.is_a?(Integer)
130
+
131
+ lkhd.selection_with_alias(field_name)
132
+ }
63
133
 
64
134
  current_root.selections.to_selections_key
65
135
  end
@@ -68,12 +138,16 @@ module GraphQL
68
138
  lookahead = query.lookahead
69
139
 
70
140
  path.map { |field_name|
71
- lookahead = lookahead.selection(field_name)
141
+ # Handle cached fields inside collections:
142
+ next field_name if field_name.is_a?(Integer)
143
+
144
+ lookahead = lookahead.selection_with_alias(field_name)
145
+ raise "Failed to look ahead the field: #{field_name}" if lookahead.is_a?(::GraphQL::Execution::Lookahead::NullLookahead)
72
146
 
73
- next field_name if lookahead.arguments.empty?
147
+ next lookahead.field.name if lookahead.arguments.empty?
74
148
 
75
149
  args = lookahead.arguments.map { |_1, _2| "#{_1}:#{traverse_argument(_2)}" }.sort.join(",")
76
- "#{field_name}(#{args})"
150
+ "#{lookahead.field.name}(#{args})"
77
151
  }.join("/")
78
152
  end
79
153
 
@@ -1,6 +1,6 @@
1
1
  require "ruby-next"
2
2
 
3
3
  require "ruby-next/language/setup"
4
- RubyNext::Language.setup_gem_load_path
4
+ RubyNext::Language.setup_gem_load_path(transpile: true)
5
5
 
6
6
  require "graphql/fragment_cache"
@@ -4,10 +4,11 @@ require "graphql"
4
4
 
5
5
  require "graphql/fragment_cache/ext/context_fragments"
6
6
  require "graphql/fragment_cache/ext/graphql_cache_key"
7
-
8
- require "graphql/fragment_cache/schema_patch"
9
7
  require "graphql/fragment_cache/object"
10
- require "graphql/fragment_cache/instrumentation"
8
+
9
+ require "graphql/fragment_cache/schema/patch"
10
+ require "graphql/fragment_cache/schema/tracer"
11
+ require "graphql/fragment_cache/schema/instrumentation"
11
12
 
12
13
  require "graphql/fragment_cache/memory_store"
13
14
 
@@ -22,8 +23,9 @@ module GraphQL
22
23
  def use(schema_defn, options = {})
23
24
  verify_interpreter!(schema_defn)
24
25
 
25
- schema_defn.instrument(:query, Instrumentation)
26
- schema_defn.extend(SchemaPatch)
26
+ schema_defn.tracer(Schema::Tracer)
27
+ schema_defn.instrument(:query, Schema::Instrumentation)
28
+ schema_defn.extend(Schema::Patch)
27
29
  end
28
30
 
29
31
  def cache_store=(store)
@@ -18,6 +18,71 @@ module GraphQL
18
18
  }.join(".")
19
19
  end
20
20
  end
21
+
22
+ refine ::GraphQL::Language::Nodes::AbstractNode do
23
+ def alias?(_)
24
+ false
25
+ end
26
+ end
27
+
28
+ refine ::GraphQL::Language::Nodes::Field do
29
+ def alias?(val)
30
+ self.alias == val
31
+ end
32
+ end
33
+
34
+ refine ::GraphQL::Execution::Lookahead do
35
+ def selection_with_alias(name, **kwargs)
36
+ return selection(name, **kwargs) if selects?(name, **kwargs)
37
+ alias_selection(name, **kwargs)
38
+ end
39
+
40
+ def alias_selection(name, selected_type: @selected_type, arguments: nil)
41
+ return alias_selections[name] if alias_selections.key?(name)
42
+
43
+ alias_node = lookup_alias_node(ast_nodes, name)
44
+ return ::GraphQL::Execution::Lookahead::NULL_LOOKAHEAD unless alias_node
45
+
46
+ next_field_name = alias_node.name
47
+
48
+ # From https://github.com/rmosolgo/graphql-ruby/blob/1a9a20f3da629e63ea8e5ee8400be82218f9edc3/lib/graphql/execution/lookahead.rb#L91
49
+ next_field_defn = get_class_based_field(selected_type, next_field_name)
50
+
51
+ alias_selections[name] =
52
+ if next_field_defn
53
+ next_nodes = []
54
+ arguments = @query.arguments_for(alias_node, next_field_defn)
55
+ arguments = arguments.is_a?(::GraphQL::Execution::Interpreter::Arguments) ? arguments.keyword_arguments : arguments
56
+ @ast_nodes.each do |ast_node|
57
+ ast_node.selections.each do |selection|
58
+ find_selected_nodes(selection, next_field_name, next_field_defn, arguments: arguments, matches: next_nodes)
59
+ end
60
+ end
61
+
62
+ if next_nodes.any?
63
+ ::GraphQL::Execution::Lookahead.new(query: @query, ast_nodes: next_nodes, field: next_field_defn, owner_type: selected_type)
64
+ else
65
+ ::GraphQL::Execution::Lookahead::NULL_LOOKAHEAD
66
+ end
67
+ else
68
+ ::GraphQL::Execution::Lookahead::NULL_LOOKAHEAD
69
+ end
70
+ end
71
+
72
+ def alias_selections
73
+ return @alias_selections if defined?(@alias_selections)
74
+ @alias_selections ||= {}
75
+ end
76
+
77
+ def lookup_alias_node(nodes, name)
78
+ return if nodes.empty?
79
+ nodes.find do |node|
80
+ return node if node.alias?(name)
81
+ child = lookup_alias_node(node.children, name)
82
+ return child if child
83
+ end
84
+ end
85
+ end
21
86
  })
22
87
 
23
88
  # Builds cache key for fragment
@@ -59,7 +124,12 @@ module GraphQL
59
124
 
60
125
  def selections_cache_key
61
126
  current_root =
62
- path.reduce(query.lookahead) { |lkhd, name| lkhd.selection(name) }
127
+ path.reduce(query.lookahead) { |lkhd, field_name|
128
+ # Handle cached fields inside collections:
129
+ next lkhd if field_name.is_a?(Integer)
130
+
131
+ lkhd.selection_with_alias(field_name)
132
+ }
63
133
 
64
134
  current_root.selections.to_selections_key
65
135
  end
@@ -68,12 +138,16 @@ module GraphQL
68
138
  lookahead = query.lookahead
69
139
 
70
140
  path.map { |field_name|
71
- lookahead = lookahead.selection(field_name)
141
+ # Handle cached fields inside collections:
142
+ next field_name if field_name.is_a?(Integer)
143
+
144
+ lookahead = lookahead.selection_with_alias(field_name)
145
+ raise "Failed to look ahead the field: #{field_name}" if lookahead.is_a?(::GraphQL::Execution::Lookahead::NullLookahead)
72
146
 
73
- next field_name if lookahead.arguments.empty?
147
+ next lookahead.field.name if lookahead.arguments.empty?
74
148
 
75
149
  args = lookahead.arguments.map { "#{_1}:#{traverse_argument(_2)}" }.sort.join(",")
76
- "#{field_name}(#{args})"
150
+ "#{lookahead.field.name}(#{args})"
77
151
  }.join("/")
78
152
  end
79
153
 
@@ -10,9 +10,7 @@ module GraphQL
10
10
  def call(query)
11
11
  return unless query.context.fragments?
12
12
 
13
- final_value = query.context.namespace(:interpreter)[:runtime].final_value
14
-
15
- query.context.fragments.each { _1.persist(final_value) }
13
+ query.context.fragments.each(&:persist)
16
14
  end
17
15
  end
18
16
  end
@@ -8,18 +8,26 @@ module GraphQL
8
8
  class Fragment
9
9
  attr_reader :options, :path, :context
10
10
 
11
+ attr_accessor :resolved_value
12
+
11
13
  def initialize(context, **options)
12
14
  @context = context
13
15
  @options = options
14
- @path = context.namespace(:interpreter)[:current_path]
16
+ @path = interpreter_context[:current_path]
15
17
  end
16
18
 
19
+ NIL_IN_CACHE = Object.new
20
+
17
21
  def read
18
- FragmentCache.cache_store.read(cache_key)
22
+ FragmentCache.cache_store.read(cache_key).tap do |cached|
23
+ return NIL_IN_CACHE if cached.nil? && FragmentCache.cache_store.exist?(cache_key)
24
+ end
19
25
  end
20
26
 
21
- def persist(final_value)
22
- value = resolve(final_value)
27
+ def persist
28
+ # Connections are not available from the runtime object, so
29
+ # we rely on Schema::Tracer to save it for us
30
+ value = resolved_value || resolve_from_runtime
23
31
  FragmentCache.cache_store.write(cache_key, value, **options)
24
32
  end
25
33
 
@@ -29,9 +37,17 @@ module GraphQL
29
37
  @cache_key ||= CacheKeyBuilder.call(path: path, query: context.query, **options)
30
38
  end
31
39
 
32
- def resolve(final_value)
40
+ def interpreter_context
41
+ context.namespace(:interpreter)
42
+ end
43
+
44
+ def resolve_from_runtime
33
45
  final_value.dig(*path)
34
46
  end
47
+
48
+ def final_value
49
+ @final_value ||= interpreter_context[:runtime].final_value
50
+ end
35
51
  end
36
52
  end
37
53
  end
@@ -23,6 +23,10 @@ module GraphQL
23
23
  @storage = {}
24
24
  end
25
25
 
26
+ def exist?(key)
27
+ storage.key?(key)
28
+ end
29
+
26
30
  def read(key)
27
31
  key = key.to_s
28
32
  storage[key]&.then do |entry|
@@ -8,21 +8,42 @@ module GraphQL
8
8
 
9
9
  # Adds #cache_fragment method
10
10
  module ObjectHelpers
11
+ extend Forwardable
12
+
11
13
  NO_OBJECT = Object.new
12
14
 
15
+ def_delegator :field, :connection?
16
+
13
17
  def cache_fragment(object_to_cache = NO_OBJECT, **options, &block)
14
18
  raise ArgumentError, "Block or argument must be provided" unless block_given? || object_to_cache != NO_OBJECT
15
19
 
16
20
  options[:object] = object_to_cache if object_to_cache != NO_OBJECT
21
+
17
22
  fragment = Fragment.new(context, options)
18
23
 
19
24
  if (cached = fragment.read)
20
- return raw_value(cached)
25
+ return nil if cached == Fragment::NIL_IN_CACHE
26
+ return restore_cached_value(cached)
27
+ end
28
+
29
+ (block_given? ? block.call : object_to_cache).tap do |resolved_value|
30
+ context.fragments << fragment
21
31
  end
32
+ end
33
+
34
+ private
22
35
 
23
- context.fragments << fragment
36
+ def restore_cached_value(cached)
37
+ # If we return connection object from resolver, Interpreter stops processing it
38
+ connection? ? cached : raw_value(cached)
39
+ end
40
+
41
+ def field
42
+ interpreter_context[:current_field]
43
+ end
24
44
 
25
- block_given? ? block.call : object_to_cache
45
+ def interpreter_context
46
+ @interpreter_context ||= context.namespace(:interpreter)
26
47
  end
27
48
  end
28
49
  end
@@ -25,7 +25,7 @@ module GraphQL
25
25
  config.graphql_fragment_cache = Config
26
26
 
27
27
  if ENV["RACK_ENV"] == "test" || ENV["RAILS_ENV"] == "test"
28
- ::Rails.application.config.graphql_fragment_cache.store = :null_store
28
+ config.graphql_fragment_cache.store = :null_store
29
29
  end
30
30
  end
31
31
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "graphql/fragment_cache/cacher"
4
+
5
+ module GraphQL
6
+ module FragmentCache
7
+ module Schema
8
+ # Adds hook for saving cached values after query is resolved
9
+ module Instrumentation
10
+ module_function
11
+
12
+ def before_query(query)
13
+ end
14
+
15
+ def after_query(query)
16
+ return unless query.valid?
17
+
18
+ Cacher.call(query)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "digest/sha1"
4
+
5
+ module GraphQL
6
+ module FragmentCache
7
+ module Schema
8
+ # Patches GraphQL::Schema to support fragment cache
9
+ module Patch
10
+ def schema_cache_key
11
+ @schema_cache_key ||= Digest::SHA1.hexdigest(to_definition)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphQL
4
+ # Plugin definition
5
+ module FragmentCache
6
+ module Schema
7
+ class Tracer
8
+ using Ext
9
+
10
+ class << self
11
+ def trace(key, data)
12
+ yield.tap do |resolved_value|
13
+ next unless connection_to_cache?(key, data)
14
+
15
+ # We need to attach connection object to fragment and save it later
16
+ context = data[:query].context
17
+ verify_connections!(context)
18
+ cache_connection(resolved_value, context)
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def connection_to_cache?(key, data)
25
+ key == "execute_field" && data[:field].connection?
26
+ end
27
+
28
+ def verify_connections!(context)
29
+ return if context.schema.new_connections?
30
+
31
+ raise StandardError,
32
+ "GraphQL::Pagination::Connections should be enabled for connection caching"
33
+ end
34
+
35
+ def cache_connection(resolved_value, context)
36
+ current_path = context.namespace(:interpreter)[:current_path]
37
+ fragment = context.fragments.find { |fragment| fragment.path == current_path }
38
+ fragment.resolved_value = resolved_value if fragment
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module GraphQL
4
4
  module FragmentCache
5
- VERSION = "0.1.3"
5
+ VERSION = "1.0.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: 0.1.3
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - DmitryTsepelev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-24 00:00:00.000000000 Z
11
+ date: 2020-06-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: graphql
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 1.10.3
19
+ version: 1.10.8
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.10.3
26
+ version: 1.10.8
27
27
  - !ruby/object:Gem::Dependency
28
- name: ruby-next-core
28
+ name: ruby-next
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.5.1
33
+ version: 0.7.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 0.5.1
40
+ version: 0.7.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: combustion
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +52,34 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activerecord
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: sqlite3
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
55
83
  - !ruby/object:Gem::Dependency
56
84
  name: rake
57
85
  requirement: !ruby/object:Gem::Requirement
@@ -121,7 +149,6 @@ files:
121
149
  - bin/console
122
150
  - bin/setup
123
151
  - lib/.rbnext/2.7/graphql/fragment_cache/cache_key_builder.rb
124
- - lib/.rbnext/2.7/graphql/fragment_cache/cacher.rb
125
152
  - lib/.rbnext/2.7/graphql/fragment_cache/ext/graphql_cache_key.rb
126
153
  - lib/graphql-fragment_cache.rb
127
154
  - lib/graphql/fragment_cache.rb
@@ -131,13 +158,14 @@ files:
131
158
  - lib/graphql/fragment_cache/ext/graphql_cache_key.rb
132
159
  - lib/graphql/fragment_cache/field_extension.rb
133
160
  - lib/graphql/fragment_cache/fragment.rb
134
- - lib/graphql/fragment_cache/instrumentation.rb
135
161
  - lib/graphql/fragment_cache/memory_store.rb
136
162
  - lib/graphql/fragment_cache/object.rb
137
163
  - lib/graphql/fragment_cache/object_helpers.rb
138
164
  - lib/graphql/fragment_cache/rails/cache_key_builder.rb
139
165
  - lib/graphql/fragment_cache/railtie.rb
140
- - lib/graphql/fragment_cache/schema_patch.rb
166
+ - lib/graphql/fragment_cache/schema/instrumentation.rb
167
+ - lib/graphql/fragment_cache/schema/patch.rb
168
+ - lib/graphql/fragment_cache/schema/tracer.rb
141
169
  - lib/graphql/fragment_cache/version.rb
142
170
  homepage: https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache
143
171
  licenses:
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module GraphQL
4
- module FragmentCache
5
- using Ext
6
-
7
- # Saves resolved fragment values to cache store
8
- module Cacher
9
- class << self
10
- def call(query)
11
- return unless query.context.fragments?
12
-
13
- final_value = query.context.namespace(:interpreter)[:runtime].final_value
14
-
15
- query.context.fragments.each { |_1| _1.persist(final_value) }
16
- end
17
- end
18
- end
19
- end
20
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "graphql/fragment_cache/cacher"
4
-
5
- module GraphQL
6
- module FragmentCache
7
- # Adds hook for saving cached values after query is resolved
8
- module Instrumentation
9
- module_function
10
-
11
- def before_query(query)
12
- end
13
-
14
- def after_query(query)
15
- return unless query.valid?
16
-
17
- Cacher.call(query)
18
- end
19
- end
20
- end
21
- end
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "digest/sha1"
4
-
5
- module GraphQL
6
- module FragmentCache
7
- # Patches GraphQL::Schema to support fragment cache
8
- module SchemaPatch
9
- def schema_cache_key
10
- @schema_cache_key ||= Digest::SHA1.hexdigest(to_definition)
11
- end
12
- end
13
- end
14
- end