cubism 0.1.0.pre10 → 0.1.0.pre11

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: 976cb8cfb5c2fe6edb6dd6e541c74361ae17dd12ce717bafadcb6ff6bdd1b9f1
4
- data.tar.gz: a3e777efd1df0423ab4754ed30fe119b6497197ec2bc8ee564304385b907849d
3
+ metadata.gz: cf5d9eed6d97039688a2f51dd5ddab248619879ad47d50abbf37bab73d7f7d56
4
+ data.tar.gz: 8120474f22abf5ee4b9bc2497e91ef2e68f41aea79f59fde4ae1c9e577a75dd7
5
5
  SHA512:
6
- metadata.gz: 163db944110832cefb97406ebc7c4c98b231fdf98d9cce25abe164469eb64d9930d5aa1689c53426605dd11e42cbb721e314430a7b1ec1b7acc37449a676f702
7
- data.tar.gz: b1c4052e437c7ebe723615e4b3316f1ac5d538aa2008b87957aca8762cd04bf61aed0f930aac42256aa07340d1c05652611fdcd47cad2f4b2e9d870393999e18
6
+ metadata.gz: fe7a0bca6d22807e0eb6b81e612ee8d435f67380a5aec20df253a86a92606642f907a67341b845159b2ae498dfcc0d7c56c1f49fb3425e1470789140adf4939e
7
+ data.tar.gz: dd6925f36a82fcfab2de5a888b1d974b151fb9a14a7c4cf76cab9f3ffde28b865790c09dd4b97b19a8284192cef644847a3c944b06e53dd2d690ef8da2a7245e
@@ -2,29 +2,27 @@ module CubismHelper
2
2
  include CableReady::StreamIdentifier
3
3
 
4
4
  def cubicle_for(resource, user, html_options: {}, appear_trigger: :connect, disappear_trigger: nil, trigger_root: nil, exclude_current_user: true, &block)
5
- filename, lineno = block.source_location
6
5
  block_location = block.source_location.join(":")
7
- resource_user_key = "#{resource.to_gid}:#{user.to_gid}"
8
- digested_block_key = ActiveSupport::Digest.hexdigest("#{block_location}:#{resource_user_key}")
6
+ block_source = Cubism::BlockSource.find_or_create(
7
+ location: block_location,
8
+ view_context: self
9
+ )
10
+
11
+ resource_gid = resource.to_gid.to_s
9
12
 
10
- # the store item (identified by block location, resource, and user) might already be present
11
- store_item = Cubism.store[digested_block_key] || Cubism::BlockStoreItem.new(
13
+ block_container = Cubism::BlockContainer.new(
12
14
  block_location: block_location,
13
- resource_gid: resource.to_gid.to_s,
15
+ block_source: block_source,
16
+ resource_gid: resource_gid,
14
17
  user_gid: user.to_gid.to_s
15
18
  )
16
19
 
17
- if Cubism.store[digested_block_key]&.block_source.blank? && !block_location.start_with?("inline template")
18
- lines = File.readlines(filename)[lineno - 1..]
19
-
20
- preprocessor = Cubism::Preprocessor.new(source: lines.join.squish, view_context: self)
21
- store_item.block_source = preprocessor.process
22
- end
20
+ digested_block_key = block_container.digest
23
21
 
24
- Cubism.store[digested_block_key] = store_item
22
+ Cubism.block_store.fetch(digested_block_key, block_container)
25
23
 
26
24
  tag.cubicle_element(
27
- identifier: signed_stream_identifier(resource.to_gid.to_s),
25
+ identifier: signed_stream_identifier(resource_gid),
28
26
  user: user.to_sgid.to_s,
29
27
  "appear-trigger": Array(appear_trigger).join(","),
30
28
  "disappear-trigger": disappear_trigger,
@@ -2,26 +2,25 @@ module CubismHelper
2
2
  include CableReady::StreamIdentifier
3
3
 
4
4
  def cubicle_for(resource, user, html_options: {}, appear_trigger: :connect, disappear_trigger: nil, trigger_root: nil, exclude_current_user: true, &block)
5
- filename, lineno = block.source_location
6
5
  block_location = block.source_location.join(":")
7
- resource_user_key = "#{resource.to_gid}:#{user.to_gid}"
8
- digested_block_key = ActiveSupport::Digest.hexdigest("#{block_location}:#{resource_user_key}")
9
6
 
10
- Cubism.store[digested_block_key] = Cubism::BlockStoreItem.new(
7
+ resource_gid = resource.to_gid.to_s
8
+
9
+ store_item = Cubism::BlockStoreItem.new(
11
10
  block_location: block_location,
12
- resource_gid: resource.to_gid.to_s,
13
- user_gid: user.to_gid.to_s
11
+ resource_gid: resource_gid,
12
+ user_gid: user.to_gid.to_s,
13
+ view_context: self
14
14
  )
15
15
 
16
- if Cubism.store[block_location].blank? && !block_location.start_with?("inline template")
17
- lines = File.readlines(filename)[lineno - 1..]
16
+ digested_block_key = store_item.digest
17
+
18
+ store_item.parse!
18
19
 
19
- preprocessor = Cubism::Preprocessor.new(source: lines.join.squish, view_context: self)
20
- Cubism.store[block_location] = preprocessor.process
21
- end
20
+ Cubism.block_store[digested_block_key] = store_item
22
21
 
23
22
  tag.cubicle_element(
24
- identifier: signed_stream_identifier(resource.to_gid.to_s),
23
+ identifier: signed_stream_identifier(resource_gid),
25
24
  user: user.to_sgid.to_s,
26
25
  "appear-trigger": Array(appear_trigger).join(","),
27
26
  "disappear-trigger": disappear_trigger,
@@ -10,4 +10,11 @@ module Cubism::Presence
10
10
  def stream_presence
11
11
  Cubism::Broadcaster.new(resource: self).broadcast
12
12
  end
13
+
14
+ def present_users_for_element_id(element_id)
15
+ users = Cubism.user_class.find(present_users.members)
16
+ users.reject! { |user| user.id == excluded_user_id_for_element_id[element_id].to_i }
17
+
18
+ users
19
+ end
13
20
  end
@@ -14,11 +14,13 @@ module Cubism
14
14
  def broadcast
15
15
  resource.cubicle_element_ids.to_a.each do |element_id|
16
16
  /cubicle-(?<block_key>.+)/ =~ element_id
17
- store_item = Cubism.store[block_key]
17
+ block_container = Cubism.block_store[block_key]
18
18
 
19
- next if store_item.blank?
19
+ next if block_container.blank?
20
20
 
21
- html = ApplicationController.render(inline: store_item.block_source, locals: {users: resource.present_users_for_element_id(element_id)})
21
+ block_source = block_container.block_source
22
+
23
+ html = ApplicationController.render(inline: block_source.source, locals: {"#{block_source.variable_name}": resource.present_users_for_element_id(element_id)})
22
24
 
23
25
  cable_ready[element_id].inner_html(
24
26
  selector: "cubicle-element##{element_id}[identifier='#{signed_stream_identifier(resource.to_global_id.to_s)}']",
@@ -1,11 +1,9 @@
1
1
  require "cable_ready"
2
- require "parser/current"
3
2
 
4
3
  module Cubism
5
4
  class Broadcaster
6
5
  include CableReady::Broadcaster
7
6
  include CableReady::StreamIdentifier
8
- include ActionView::Helpers
9
7
 
10
8
  attr_reader :resource
11
9
 
@@ -16,33 +14,15 @@ module Cubism
16
14
  def broadcast
17
15
  resource.cubicle_element_ids.to_a.each do |element_id|
18
16
  /cubicle-(?<block_key>.+)/ =~ element_id
19
- block_store_item = Cubism.store[block_key]
17
+ store_item = Cubism.block_store[block_key]
20
18
 
21
- next if block_store_item.blank?
19
+ next if store_item.blank?
22
20
 
23
- block_source = Cubism.store[block_store_item.block_location]
24
- erubi = ActionView::Template::Handlers::ERB::Erubi.new(block_source)
25
- ast = Parser::CurrentRuby.parse erubi.src
26
-
27
- # html = ApplicationController.render(inline: block_source, locals: {current_user: block_store_item.user, "@project": block_store_item.resource, users: resource.present_users_for_element_id(element_id)})
28
-
29
- # binding.pry
30
-
31
- # context = ActionView::Base.with_view_paths(ActionController::Base.view_paths)
32
- # erubi = ActionView::Template::Handlers::ERB::Erubi.new(File.read(filename), filename: filename)
33
- # context = ApplicationController.new.view_context
34
-
35
- # filename, lineno = block_store_item.block_location.split
36
-
37
- # binding.pry
38
-
39
- # block = Cubism.store[block_key].block
40
- # view_context = Cubism.store[block_key].context
41
- # html = view_context.capture(resource.present_users_for_element_id(element_id), &block)
21
+ html = ApplicationController.render(inline: store_item.block_source, locals: {"#{store_item.block_variable_name}": resource.present_users_for_element_id(element_id)})
42
22
 
43
23
  cable_ready[element_id].inner_html(
44
24
  selector: "cubicle-element##{element_id}[identifier='#{signed_stream_identifier(resource.to_global_id.to_s)}']",
45
- html: "#{resource.present_users_for_element_id(element_id).map(&:id)}"
25
+ html: html
46
26
  ).broadcast
47
27
  end
48
28
  end
@@ -1,29 +1,32 @@
1
1
  module Cubism
2
2
  class CubicleBlockStore
3
- include Singleton
4
-
5
3
  delegate_missing_to :@blocks
6
4
 
7
5
  def initialize
8
- @blocks = {}
6
+ @blocks = Kredis.hash "cubism-blocks"
9
7
  end
10
8
 
11
9
  def [](key)
12
- @blocks[key]
10
+ Marshal.load(@blocks[key]) if @blocks[key]
13
11
  end
14
12
 
15
13
  def []=(key, value)
16
14
  mutex.synchronize do
17
- @blocks[key] = value
15
+ @blocks[key] = Marshal.dump value
18
16
  end
19
17
  end
20
18
 
21
19
  def clear
22
20
  mutex.synchronize do
23
- @blocks.clear
21
+ # kredis #remove
22
+ @blocks.remove
24
23
  end
25
24
  end
26
25
 
26
+ def size
27
+ @blocks.to_h.size
28
+ end
29
+
27
30
  private
28
31
 
29
32
  def mutex
@@ -31,7 +34,7 @@ module Cubism
31
34
  end
32
35
  end
33
36
 
34
- BlockStoreItem = Struct.new(:block_location, :user_gid, :resource_gid, keyword_init: true) do
37
+ BlockStoreItem = Struct.new(:block_location, :block_source, :user_gid, :resource_gid, keyword_init: true) do
35
38
  def user
36
39
  GlobalID::Locator.locate self[:user_gid]
37
40
  end
@@ -39,5 +42,15 @@ module Cubism
39
42
  def resource
40
43
  GlobalID::Locator.locate self[:resource_gid]
41
44
  end
45
+
46
+ def marshal_dump
47
+ to_h
48
+ end
49
+
50
+ def marshal_load(serialized_item)
51
+ %i[block_location block_source user_gid resource_gid].each do |arg|
52
+ send("#{arg}=", serialized_item[arg])
53
+ end
54
+ end
42
55
  end
43
56
  end
File without changes
@@ -0,0 +1,136 @@
1
+ module Cubism
2
+ class CubicleStore
3
+ delegate_missing_to :@blocks
4
+
5
+ def initialize(key)
6
+ @blocks = Kredis.hash key
7
+ end
8
+
9
+ def [](key)
10
+ Marshal.load(@blocks[key]) if @blocks[key]
11
+ end
12
+
13
+ def []=(key, value)
14
+ mutex.synchronize do
15
+ @blocks[key] = Marshal.dump value
16
+ end
17
+ end
18
+
19
+ def fetch(key, value = nil, &block)
20
+ if self[key].nil?
21
+ yield value if block
22
+ self[key] = value
23
+ end
24
+
25
+ self[key]
26
+ end
27
+
28
+ def clear
29
+ mutex.synchronize do
30
+ # kredis #remove
31
+ @blocks.remove
32
+ end
33
+ end
34
+
35
+ def size
36
+ @blocks.to_h.size
37
+ end
38
+
39
+ private
40
+
41
+ def mutex
42
+ @mutex ||= Mutex.new
43
+ end
44
+ end
45
+
46
+ # Container for cubicle blocks
47
+ BlockContainer = Struct.new(
48
+ :block_location,
49
+ :block_source,
50
+ :user_gid,
51
+ :resource_gid,
52
+ keyword_init: true
53
+ ) do
54
+ def initialize(*args)
55
+ super
56
+
57
+ @filename, _lineno = block_location.split(":")
58
+ end
59
+
60
+ def user
61
+ GlobalID::Locator.locate self[:user_gid]
62
+ end
63
+
64
+ def resource
65
+ GlobalID::Locator.locate self[:resource_gid]
66
+ end
67
+
68
+ def digest
69
+ resource_user_key = [resource_gid, user_gid].join(":")
70
+
71
+ ActiveSupport::Digest.hexdigest("#{block_location}:#{File.read(@filename)}:#{resource_user_key}")
72
+ end
73
+
74
+ def marshal_dump
75
+ to_h.merge(block_source: block_source.digest)
76
+ end
77
+
78
+ def marshal_load(serialized_item)
79
+ members.excluding(:block_source).each do |arg|
80
+ send("#{arg}=", serialized_item[arg])
81
+ end
82
+
83
+ self.block_source = Cubism.source_store[serialized_item[:block_source]]
84
+ end
85
+ end
86
+
87
+ # Container for cubicle block sources
88
+ BlockSource = Struct.new(
89
+ :location,
90
+ :source,
91
+ :variable_name,
92
+ :view_context,
93
+ keyword_init: true
94
+ ) do
95
+ def self.find_or_create(location:, view_context:)
96
+ instance = new(location: location, view_context: view_context)
97
+
98
+ Cubism.source_store.fetch(instance.digest, instance) do |instance|
99
+ instance.parse!
100
+ end
101
+
102
+ instance
103
+ end
104
+
105
+ def initialize(*args)
106
+ super
107
+
108
+ @filename, @lineno = location.split(":")
109
+ @lineno = @lineno.to_i
110
+ end
111
+
112
+ def parse!
113
+ return if location.start_with?("inline template")
114
+
115
+ lines = File.readlines(@filename)[@lineno - 1..]
116
+
117
+ preprocessor = Cubism::Preprocessor.new(source: lines.join.squish, view_context: view_context)
118
+ self.variable_name = preprocessor.block_variable_name
119
+ self.source = preprocessor.process
120
+ end
121
+
122
+ def digest
123
+ ActiveSupport::Digest.hexdigest("#{location}:#{File.read(@filename)}")
124
+ end
125
+
126
+ def marshal_dump
127
+ to_h.except(:view_context)
128
+ end
129
+
130
+ def marshal_load(serialized_item)
131
+ members.excluding(:view_context).each do |arg|
132
+ send("#{arg}=", serialized_item[arg])
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,136 @@
1
+ module Cubism
2
+ class CubicleStore
3
+ delegate_missing_to :@blocks
4
+
5
+ def initialize(key)
6
+ @blocks = Kredis.hash key
7
+ end
8
+
9
+ def [](key)
10
+ Marshal.load(@blocks[key]) if @blocks[key]
11
+ end
12
+
13
+ def []=(key, value)
14
+ mutex.synchronize do
15
+ @blocks[key] = Marshal.dump value
16
+ end
17
+ end
18
+
19
+ def fetch(key, value = nil, &block)
20
+ if self[key].nil?
21
+ yield value if block
22
+ self[key] = value
23
+ end
24
+
25
+ self[key]
26
+ end
27
+
28
+ def clear
29
+ mutex.synchronize do
30
+ # kredis #remove
31
+ @blocks.remove
32
+ end
33
+ end
34
+
35
+ def size
36
+ @blocks.to_h.size
37
+ end
38
+
39
+ private
40
+
41
+ def mutex
42
+ @mutex ||= Mutex.new
43
+ end
44
+ end
45
+
46
+ # Container for cubicle blocks
47
+ BlockStoreItem = Struct.new(
48
+ :block_location,
49
+ :block_source,
50
+ :user_gid,
51
+ :resource_gid,
52
+ keyword_init: true
53
+ ) do
54
+ def initialize(*args)
55
+ super
56
+
57
+ @filename, _lineno = block_location.split(":")
58
+ end
59
+
60
+ def user
61
+ GlobalID::Locator.locate self[:user_gid]
62
+ end
63
+
64
+ def resource
65
+ GlobalID::Locator.locate self[:resource_gid]
66
+ end
67
+
68
+ def digest
69
+ resource_user_key = [resource_gid, user_gid].join(":")
70
+
71
+ ActiveSupport::Digest.hexdigest("#{block_location}:#{File.read(@filename)}:#{resource_user_key}")
72
+ end
73
+
74
+ def marshal_dump
75
+ to_h.reverse_merge(block_source: block_source.digest)
76
+ end
77
+
78
+ def marshal_load(serialized_item)
79
+ members.excluding(:block_source).each do |arg|
80
+ send("#{arg}=", serialized_item[arg])
81
+ end
82
+
83
+ self.block_source = Cubism.source_store(serialized_item[:block_source])
84
+ end
85
+ end
86
+
87
+ # Container for cubicle block sources
88
+ BlockSource = Struct.new(
89
+ :location,
90
+ :source,
91
+ :variable_name,
92
+ :view_context,
93
+ keyword_init: true
94
+ ) do
95
+ def self.find_or_create(location:, view_context:)
96
+ instance = new(location: location, view_context: view_context)
97
+
98
+ Cubism.source_store.fetch(instance.digest, instance) do |instance|
99
+ instance.parse!
100
+ end
101
+
102
+ instance
103
+ end
104
+
105
+ def initialize(*args)
106
+ super
107
+
108
+ @filename, @lineno = location.split(":")
109
+ @lineno = @lineno.to_i
110
+ end
111
+
112
+ def parse!
113
+ return if location.start_with?("inline template")
114
+
115
+ lines = File.readlines(@filename)[@lineno - 1..]
116
+
117
+ preprocessor = Cubism::Preprocessor.new(source: lines.join.squish, view_context: view_context)
118
+ self.variable_name = preprocessor.block_variable_name
119
+ self.source = preprocessor.process
120
+ end
121
+
122
+ def digest
123
+ ActiveSupport::Digest.hexdigest("#{location}:#{File.read(@filename)}")
124
+ end
125
+
126
+ def marshal_dump
127
+ to_h.except(:view_context)
128
+ end
129
+
130
+ def marshal_load(serialized_item)
131
+ members.excluding(:view_context).each do |arg|
132
+ send("#{arg}=", serialized_item[arg])
133
+ end
134
+ end
135
+ end
136
+ end
data/lib/cubism/engine.rb CHANGED
@@ -1,7 +1,8 @@
1
1
  module Cubism
2
2
  class Engine < ::Rails::Engine
3
- initializer "cubism.store" do
4
- Cubism.store = Cubism::CubicleBlockStore.new
3
+ initializer "cubism.stores" do
4
+ Cubism.block_store = Cubism::CubicleStore.new("cubism-blocks")
5
+ Cubism.source_store = Cubism::CubicleStore.new("cubism-source")
5
6
  end
6
7
  end
7
8
  end
@@ -1,4 +1,7 @@
1
1
  module Cubism
2
2
  class Engine < ::Rails::Engine
3
+ initializer "cubism.block_store" do
4
+ Cubism.block_store = Cubism::CubicleBlockStore.new
5
+ end
3
6
  end
4
7
  end
@@ -1,8 +1,11 @@
1
1
  module Cubism
2
2
  class Preprocessor
3
+ attr_reader :block_variable_name
4
+
3
5
  def initialize(source:, view_context:)
4
- match_data = /<%=\s+cubicle_for.+\|.+\|\s+%>/.match(source)
6
+ match_data = /<%=\s+cubicle_for.+?\|(\w+)\|\s+%>/.match(source)
5
7
  start_pos = match_data&.end(0) || 0
8
+ @block_variable_name = match_data[1] if match_data
6
9
  @source = source[start_pos..]
7
10
  @view_context = view_context
8
11
  end
@@ -1,7 +1,8 @@
1
1
  module Cubism
2
2
  class Preprocessor
3
3
  def initialize(source:, view_context:)
4
- start_pos = /<%= cubicle_for/ =~ source
4
+ match_data = /<%=\s+cubicle_for.+\|.+\|\s+%>/.match(source)
5
+ start_pos = match_data&.end(0) || 0
5
6
  @source = source[start_pos..]
6
7
  @view_context = view_context
7
8
  end
@@ -16,10 +17,13 @@ module Cubism
16
17
  @source
17
18
  end
18
19
 
20
+ private
21
+
19
22
  def do_parse
20
23
  ActionView::Template::Handlers::ERB::Erubi.new(@source).evaluate(@view_context)
21
24
  rescue SyntaxError
22
- @source = @source[..-2]
25
+ end_at_end = /(<%\s+end\s+%>)\z/.match(@source)
26
+ @source = end_at_end ? @source[..-(end_at_end[0].length + 1)] : @source[..-2]
23
27
  do_parse
24
28
  end
25
29
  end
@@ -1,3 +1,3 @@
1
1
  module Cubism
2
- VERSION = "0.1.0.pre10"
2
+ VERSION = "0.1.0.pre11"
3
3
  end
data/lib/cubism.rb CHANGED
@@ -3,7 +3,7 @@ require "kredis"
3
3
  require "cubism/version"
4
4
  require "cubism/engine"
5
5
  require "cubism/broadcaster"
6
- require "cubism/cubicle_block_store"
6
+ require "cubism/cubicle_store"
7
7
  require "cubism/preprocessor"
8
8
 
9
9
  module Cubism
@@ -14,5 +14,6 @@ module Cubism
14
14
 
15
15
  mattr_accessor :user_class, instance_writer: false, instance_reader: false
16
16
 
17
- mattr_accessor :store, instance_reader: false
17
+ mattr_accessor :block_store, instance_reader: false
18
+ mattr_accessor :source_store, instance_reader: false
18
19
  end
data/lib/cubism.rb~ CHANGED
@@ -14,5 +14,5 @@ module Cubism
14
14
 
15
15
  mattr_accessor :user_class, instance_writer: false, instance_reader: false
16
16
 
17
- mattr_reader :store, instance_reader: false, default: Cubism::CubicleBlockStore.instance
17
+ mattr_accessor :block_store, instance_reader: false
18
18
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cubism
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre10
4
+ version: 0.1.0.pre11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julian Rubisch
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-24 00:00:00.000000000 Z
11
+ date: 2022-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -145,8 +145,10 @@ files:
145
145
  - lib/cubism.rb~
146
146
  - lib/cubism/broadcaster.rb
147
147
  - lib/cubism/broadcaster.rb~
148
- - lib/cubism/cubicle_block_store.rb
149
148
  - lib/cubism/cubicle_block_store.rb~
149
+ - lib/cubism/cubicle_source_store.rb~
150
+ - lib/cubism/cubicle_store.rb
151
+ - lib/cubism/cubicle_store.rb~
150
152
  - lib/cubism/engine.rb
151
153
  - lib/cubism/engine.rb~
152
154
  - lib/cubism/parser.rb~
@@ -1,56 +0,0 @@
1
- module Cubism
2
- class CubicleBlockStore
3
- delegate_missing_to :@blocks
4
-
5
- def initialize
6
- @blocks = Kredis.hash "cubism-blocks"
7
- end
8
-
9
- def [](key)
10
- Marshal.load(@blocks[key]) if @blocks[key]
11
- end
12
-
13
- def []=(key, value)
14
- mutex.synchronize do
15
- @blocks[key] = Marshal.dump value
16
- end
17
- end
18
-
19
- def clear
20
- mutex.synchronize do
21
- # kredis #remove
22
- @blocks.remove
23
- end
24
- end
25
-
26
- def size
27
- @blocks.to_h.size
28
- end
29
-
30
- private
31
-
32
- def mutex
33
- @mutex ||= Mutex.new
34
- end
35
- end
36
-
37
- BlockStoreItem = Struct.new(:block_location, :block_source, :user_gid, :resource_gid, keyword_init: true) do
38
- def user
39
- GlobalID::Locator.locate self[:user_gid]
40
- end
41
-
42
- def resource
43
- GlobalID::Locator.locate self[:resource_gid]
44
- end
45
-
46
- def marshal_dump
47
- to_h
48
- end
49
-
50
- def marshal_load(serialized_item)
51
- %i[block_location block_source user_gid resource_gid].each do |arg|
52
- send("#{arg}=", serialized_item[arg])
53
- end
54
- end
55
- end
56
- end