graphql-fragment_cache 0.1.6 → 0.1.7

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: d83b3ff9d3e9cc91b6f013214d2cc4d97c6d2fc8bd377bf38d1f68dd7f935c23
4
- data.tar.gz: d349157e8c6856c06b5a3ae76915399ae77fc04153093ef9551bb75b45629cb4
3
+ metadata.gz: 1c1bfd3dbaadd053ae1e47ac16d1cb244410adeae3424b30d58b04516447bfe6
4
+ data.tar.gz: 10de0c52b16423e65db745433a61aef94c795edca3b4b47c3ef834f7118d0a5f
5
5
  SHA512:
6
- metadata.gz: 759813c8b9ae4373d9890519aa88573eb9a504771eca25ea7d7ddc2a35b972f172e1fb7e86bbd2f52447886e3c781178cfc7491c9a7257ce436ae411a32395fb
7
- data.tar.gz: 78c75d761fc3154dd4a4622a36c5b0f7bbc4b26c31eb4bf3e3c6be4423be8ae64923d7207f02217142c213fa80e039410e2d079403c0258efd82543d9866e41d
6
+ metadata.gz: 54ad113a7ef913df0c283c130bae045621dd99298bb1e658e6a4e00440fa29a6ac3d39f45789b49f9cc8a09ddaf34fe4af18560ebbc1c41d73e33d6e539e9b10
7
+ data.tar.gz: b36091bf683d1018e47ae0fcfd5e69fedad20d4a7b20687a67315d721efa63a5b5df158cb8142ed6342b5ae77c3bd41d08a281299d16f0fcd10d74107e5db78e
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.1.7 (2020-06-02)
6
+
7
+ - [PR#23](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/23) Avoid extra queries after restoring connection from cache ([@DmitryTsepelev][])
8
+
5
9
  ## 0.1.6 (2020-05-30)
6
10
 
7
11
  - [PR#22](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache/pull/22) Properly cache entites inside collections ([@DmitryTsepelev][])
@@ -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)
@@ -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
@@ -6,22 +6,24 @@ module GraphQL
6
6
  module FragmentCache
7
7
  # Represents a single fragment to cache
8
8
  class Fragment
9
- attr_reader :options, :path, :context, :raw_connection
9
+ attr_reader :options, :path, :context
10
10
 
11
- attr_writer :raw_connection
11
+ attr_accessor :resolved_value
12
12
 
13
13
  def initialize(context, **options)
14
14
  @context = context
15
15
  @options = options
16
- @path = context.namespace(:interpreter)[:current_path]
16
+ @path = interpreter_context[:current_path]
17
17
  end
18
18
 
19
19
  def read
20
20
  FragmentCache.cache_store.read(cache_key)
21
21
  end
22
22
 
23
- def persist(final_value)
24
- value = raw_connection || resolve(final_value)
23
+ def persist
24
+ # Connections are not available from the runtime object, so
25
+ # we rely on Schema::Tracer to save it for us
26
+ value = resolved_value || resolve_from_runtime
25
27
  FragmentCache.cache_store.write(cache_key, value, **options)
26
28
  end
27
29
 
@@ -31,9 +33,17 @@ module GraphQL
31
33
  @cache_key ||= CacheKeyBuilder.call(path: path, query: context.query, **options)
32
34
  end
33
35
 
34
- def resolve(final_value)
36
+ def interpreter_context
37
+ context.namespace(:interpreter)
38
+ end
39
+
40
+ def resolve_from_runtime
35
41
  final_value.dig(*path)
36
42
  end
43
+
44
+ def final_value
45
+ @final_value ||= interpreter_context[:runtime].final_value
46
+ end
37
47
  end
38
48
  end
39
49
  end
@@ -6,8 +6,6 @@ module GraphQL
6
6
  module FragmentCache
7
7
  using Ext
8
8
 
9
- RawConnection = Struct.new(:items, :nodes, :paged_nodes_offset, :has_previous_page, :has_next_page)
10
-
11
9
  # Adds #cache_fragment method
12
10
  module ObjectHelpers
13
11
  extend Forwardable
@@ -28,35 +26,15 @@ module GraphQL
28
26
  end
29
27
 
30
28
  (block_given? ? block.call : object_to_cache).tap do |resolved_value|
31
- cache_value(resolved_value, fragment)
29
+ context.fragments << fragment
32
30
  end
33
31
  end
34
32
 
35
33
  private
36
34
 
37
35
  def restore_cached_value(cached)
38
- connection? ? restore_cached_connection(cached) : raw_value(cached)
39
- end
40
-
41
- def cache_value(resolved_value, fragment)
42
- if connection?
43
- unless context.schema.new_connections?
44
- raise StandardError,
45
- "GraphQL::Pagination::Connections should be enabled for connection caching"
46
- end
47
-
48
- connection = wrap_connection(resolved_value)
49
-
50
- fragment.raw_connection = RawConnection.new(
51
- connection.items,
52
- connection.nodes,
53
- connection.instance_variable_get(:@paged_nodes_offset),
54
- connection.has_previous_page,
55
- connection.has_next_page
56
- )
57
- end
58
-
59
- context.fragments << fragment
36
+ # If we return connection object from resolver, Interpreter stops processing it
37
+ connection? ? cached : raw_value(cached)
60
38
  end
61
39
 
62
40
  def field
@@ -66,19 +44,6 @@ module GraphQL
66
44
  def interpreter_context
67
45
  @interpreter_context ||= context.namespace(:interpreter)
68
46
  end
69
-
70
- def restore_cached_connection(raw_connection)
71
- wrap_connection(raw_connection.items).tap do |connection|
72
- connection.instance_variable_set(:@nodes, raw_connection.nodes)
73
- connection.instance_variable_set(:@paged_nodes_offset, raw_connection.paged_nodes_offset)
74
- connection.instance_variable_set(:@has_previous_page, raw_connection.has_previous_page)
75
- connection.instance_variable_set(:@has_next_page, raw_connection.has_next_page)
76
- end
77
- end
78
-
79
- def wrap_connection(object)
80
- context.schema.connections.wrap(field, object, interpreter_context[:current_arguments], context)
81
- end
82
47
  end
83
48
  end
84
49
  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.6"
5
+ VERSION = "0.1.7"
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.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - DmitryTsepelev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-30 00:00:00.000000000 Z
11
+ date: 2020-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: graphql
@@ -149,7 +149,6 @@ files:
149
149
  - bin/console
150
150
  - bin/setup
151
151
  - lib/.rbnext/2.7/graphql/fragment_cache/cache_key_builder.rb
152
- - lib/.rbnext/2.7/graphql/fragment_cache/cacher.rb
153
152
  - lib/.rbnext/2.7/graphql/fragment_cache/ext/graphql_cache_key.rb
154
153
  - lib/graphql-fragment_cache.rb
155
154
  - lib/graphql/fragment_cache.rb
@@ -159,13 +158,14 @@ files:
159
158
  - lib/graphql/fragment_cache/ext/graphql_cache_key.rb
160
159
  - lib/graphql/fragment_cache/field_extension.rb
161
160
  - lib/graphql/fragment_cache/fragment.rb
162
- - lib/graphql/fragment_cache/instrumentation.rb
163
161
  - lib/graphql/fragment_cache/memory_store.rb
164
162
  - lib/graphql/fragment_cache/object.rb
165
163
  - lib/graphql/fragment_cache/object_helpers.rb
166
164
  - lib/graphql/fragment_cache/rails/cache_key_builder.rb
167
165
  - lib/graphql/fragment_cache/railtie.rb
168
- - 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
169
169
  - lib/graphql/fragment_cache/version.rb
170
170
  homepage: https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache
171
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