isomorfeus-data 1.0.0.zeta25 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +47 -21
  3. data/README.md +38 -46
  4. data/lib/isomorfeus/data/attribute_support.rb +176 -176
  5. data/lib/isomorfeus/data/config.rb +79 -110
  6. data/lib/isomorfeus/data/element_validator.rb +147 -147
  7. data/lib/isomorfeus/data/ferret_accelerator.rb +66 -0
  8. data/lib/isomorfeus/data/field_support.rb +110 -0
  9. data/lib/isomorfeus/data/generic_class_api.rb +136 -116
  10. data/lib/isomorfeus/data/generic_instance_api.rb +150 -145
  11. data/lib/isomorfeus/data/hamster_accelerator.rb +87 -0
  12. data/lib/isomorfeus/data/hamster_storage_expander.rb +94 -0
  13. data/lib/isomorfeus/data/handler/generic.rb +134 -138
  14. data/lib/isomorfeus/data/reducer.rb +30 -30
  15. data/lib/isomorfeus/data/version.rb +4 -4
  16. data/lib/isomorfeus-data.rb +56 -64
  17. data/lib/isomorfeus_data/lucid_document/base.rb +10 -0
  18. data/lib/isomorfeus_data/lucid_document/mixin.rb +148 -0
  19. data/lib/isomorfeus_data/lucid_file/base.rb +10 -0
  20. data/lib/isomorfeus_data/lucid_file/mixin.rb +217 -0
  21. data/lib/isomorfeus_data/lucid_object/base.rb +10 -0
  22. data/lib/isomorfeus_data/lucid_object/mixin.rb +216 -0
  23. data/lib/isomorfeus_data/lucid_query/base.rb +10 -0
  24. data/lib/isomorfeus_data/lucid_query/mixin.rb +81 -0
  25. data/lib/isomorfeus_data/lucid_query_result.rb +97 -0
  26. data/opal/uri/common.rb +18 -0
  27. data/opal/uri/generic.rb +47 -0
  28. data/opal/uri.rb +29 -0
  29. metadata +85 -96
  30. data/lib/isomorfeus/data/handler/arango.rb +0 -56
  31. data/lib/isomorfeus/data/handler/object_call.rb +0 -40
  32. data/lib/isomorfeus/data/handler/object_store.rb +0 -40
  33. data/lib/isomorfeus_data/lucid_data/array/base.rb +0 -13
  34. data/lib/isomorfeus_data/lucid_data/array/mixin.rb +0 -580
  35. data/lib/isomorfeus_data/lucid_data/collection/base.rb +0 -13
  36. data/lib/isomorfeus_data/lucid_data/collection/finders.rb +0 -83
  37. data/lib/isomorfeus_data/lucid_data/collection/mixin.rb +0 -737
  38. data/lib/isomorfeus_data/lucid_data/composition/base.rb +0 -13
  39. data/lib/isomorfeus_data/lucid_data/composition/mixin.rb +0 -234
  40. data/lib/isomorfeus_data/lucid_data/document/base.rb +0 -13
  41. data/lib/isomorfeus_data/lucid_data/document/mixin.rb +0 -9
  42. data/lib/isomorfeus_data/lucid_data/edge/base.rb +0 -13
  43. data/lib/isomorfeus_data/lucid_data/edge/mixin.rb +0 -286
  44. data/lib/isomorfeus_data/lucid_data/edge_collection/base.rb +0 -13
  45. data/lib/isomorfeus_data/lucid_data/edge_collection/finders.rb +0 -134
  46. data/lib/isomorfeus_data/lucid_data/edge_collection/mixin.rb +0 -747
  47. data/lib/isomorfeus_data/lucid_data/generic_collection.rb +0 -4
  48. data/lib/isomorfeus_data/lucid_data/generic_edge.rb +0 -4
  49. data/lib/isomorfeus_data/lucid_data/generic_edge_collection.rb +0 -4
  50. data/lib/isomorfeus_data/lucid_data/generic_node.rb +0 -4
  51. data/lib/isomorfeus_data/lucid_data/graph/base.rb +0 -13
  52. data/lib/isomorfeus_data/lucid_data/graph/finders.rb +0 -141
  53. data/lib/isomorfeus_data/lucid_data/graph/mixin.rb +0 -489
  54. data/lib/isomorfeus_data/lucid_data/hash/base.rb +0 -13
  55. data/lib/isomorfeus_data/lucid_data/hash/mixin.rb +0 -427
  56. data/lib/isomorfeus_data/lucid_data/link/base.rb +0 -13
  57. data/lib/isomorfeus_data/lucid_data/link/mixin.rb +0 -9
  58. data/lib/isomorfeus_data/lucid_data/link_collection/base.rb +0 -13
  59. data/lib/isomorfeus_data/lucid_data/link_collection/mixin.rb +0 -9
  60. data/lib/isomorfeus_data/lucid_data/node/base.rb +0 -13
  61. data/lib/isomorfeus_data/lucid_data/node/mixin.rb +0 -232
  62. data/lib/isomorfeus_data/lucid_data/query/base.rb +0 -13
  63. data/lib/isomorfeus_data/lucid_data/query/mixin.rb +0 -83
  64. data/lib/isomorfeus_data/lucid_data/query_result.rb +0 -95
  65. data/lib/isomorfeus_data/lucid_data/vertex/base.rb +0 -13
  66. data/lib/isomorfeus_data/lucid_data/vertex/mixin.rb +0 -9
  67. data/lib/lucid_arango/collection/base.rb +0 -13
  68. data/lib/lucid_arango/collection/mixin.rb +0 -18
  69. data/lib/lucid_arango/document/base.rb +0 -13
  70. data/lib/lucid_arango/document/mixin.rb +0 -9
  71. data/lib/lucid_arango/edge/base.rb +0 -13
  72. data/lib/lucid_arango/edge/mixin.rb +0 -18
  73. data/lib/lucid_arango/edge_collection/base.rb +0 -13
  74. data/lib/lucid_arango/edge_collection/mixin.rb +0 -18
  75. data/lib/lucid_arango/graph/base.rb +0 -13
  76. data/lib/lucid_arango/graph/mixin.rb +0 -18
  77. data/lib/lucid_arango/node/base.rb +0 -13
  78. data/lib/lucid_arango/node/mixin.rb +0 -79
  79. data/lib/lucid_arango/object/base.rb +0 -11
  80. data/lib/lucid_arango/object/mixin.rb +0 -158
  81. data/lib/lucid_arango/remote_object/base.rb +0 -11
  82. data/lib/lucid_arango/remote_object/mixin.rb +0 -17
  83. data/lib/lucid_arango/vertex/base.rb +0 -13
  84. data/lib/lucid_arango/vertex/mixin.rb +0 -9
@@ -1,232 +0,0 @@
1
- module LucidData
2
- module Node
3
- module Mixin
4
- def self.included(base)
5
- base.include(Isomorfeus::Data::AttributeSupport)
6
- base.extend(Isomorfeus::Data::GenericClassApi)
7
- base.include(Isomorfeus::Data::GenericInstanceApi)
8
-
9
- def changed?
10
- @_changed
11
- end
12
-
13
- def changed!
14
- @_collection.changed! if @_collection
15
- @_composition.changed! if @_composition
16
- @_changed = true
17
- end
18
-
19
- def collection
20
- @_collection
21
- end
22
-
23
- def collection=(c)
24
- @_collection = c
25
- end
26
-
27
- def graph
28
- @_collection&.graph
29
- end
30
-
31
- def composition
32
- @_composition
33
- end
34
-
35
- def composition=(c)
36
- @_composition = c
37
- end
38
-
39
- def edges
40
- graph&.edges_for_node(self)
41
- end
42
-
43
- def linked_nodes
44
- graph&.linked_nodes_for_node(self)
45
- end
46
-
47
- def to_transport
48
- hash = { 'attributes' => _get_selected_attributes }
49
- hash.merge!('revision' => revision) if revision
50
- result = { @class_name => { @key => hash }}
51
- result.deep_merge!(@class_name => { @previous_key => { new_key: @key}}) if @previous_key
52
- result
53
- end
54
-
55
- if RUBY_ENGINE == 'opal'
56
- def initialize(key:, revision: nil, attributes: nil, collection: nil, composition: nil)
57
- @key = key.to_s
58
- @class_name = self.class.name
59
- @class_name = @class_name.split('>::').last if @class_name.start_with?('#<')
60
- _update_paths
61
- @_revision = revision ? revision : Redux.fetch_by_path(:data_state, :revision, @class_name, @key)
62
- @_collection = collection
63
- @_composition = composition
64
- @_changed = false
65
- loaded = loaded?
66
- if attributes
67
- _validate_attributes(attributes)
68
- if loaded
69
- raw_attributes = Redux.fetch_by_path(*@_store_path)
70
- if `raw_attributes === null`
71
- @_changed_attributes = !attributes ? {} : attributes
72
- elsif raw_attributes && !attributes.nil? && ::Hash.new(raw_attributes) != attributes
73
- @_changed_attributes = attributes
74
- end
75
- else
76
- @_changed_attributes = attributes
77
- end
78
- else
79
- @_changed_attributes = {}
80
- end
81
- end
82
-
83
- def _load_from_store!
84
- @_changed_attributes = {}
85
- @_changed = false
86
- end
87
-
88
- def _update_paths
89
- @_store_path = [:data_state, @class_name, @key, :attributes]
90
- end
91
-
92
- def each(&block)
93
- attributes.each(&block)
94
- end
95
-
96
- def [](name)
97
- _get_attribute(name)
98
- end
99
-
100
- def []=(name, val)
101
- _validate_attribute(name, val)
102
- changed!
103
- @_changed_attributes[name] = val
104
- end
105
-
106
- def method_missing(method_name, *args, &block)
107
- if graph
108
- singular_name = `method_name.endsWith('s')` ? method_name.singularize : method_name
109
- node_edges = edges
110
- sid = to_sid
111
- camelized_singular = singular_name.camelize
112
-
113
- if method_name == singular_name
114
- # return one node
115
- node_edges.each do |edge|
116
- from_sid = edge.from_as_sid
117
- to_sid = edge.to_as_sid
118
- node = if from_sid[0] == camelized_singular && to_sid == sid
119
- edge.from
120
- elsif to_sid[0] == camelized_singular && from_sid == sid
121
- edge.to
122
- end
123
- return node if node
124
- end
125
- nil
126
- elsif method_name == method_name.pluralize
127
- # return all nodes
128
- nodes = []
129
- node_edges.each do |edge|
130
- from_sid = edge.from_as_sid
131
- to_sid = edge.to_as_sid
132
- node = if from_sid[0] == camelized_singular && to_sid == sid
133
- edge.from
134
- elsif to_sid[0] == camelized_singular && from_sid == sid
135
- edge.to
136
- end
137
- nodes << node if node
138
- end
139
- return nodes
140
- end
141
- else
142
- super(method_name, *args, &block)
143
- end
144
- end
145
- else # RUBY_ENGINE
146
- Isomorfeus.add_valid_data_class(base) unless base == LucidData::Node::Base || base == LucidData::Document::Base || base == LucidData::Vertex::Base
147
-
148
- base.instance_exec do
149
- def instance_from_transport(instance_data, _included_items_data)
150
- key = instance_data[self.name].keys.first
151
- revision = instance_data[self.name][key].key?('revision') ? instance_data[self.name][key]['revision'] : nil
152
- attributes = instance_data[self.name][key].key?('attributes') ? instance_data[self.name][key]['attributes'].transform_keys!(&:to_sym) : nil
153
- new(key: key, revision: revision, attributes: attributes)
154
- end
155
- end
156
-
157
- def initialize(key:, revision: nil, attributes: nil, collection: nil, composition: nil)
158
- @key = key.to_s
159
- @class_name = self.class.name
160
- @class_name = @class_name.split('>::').last if @class_name.start_with?('#<')
161
- @_revision = revision
162
- @_collection = collection
163
- @_composition = composition
164
- @_changed = false
165
- attributes = {} unless attributes
166
- _validate_attributes(attributes) if attributes
167
- @_raw_attributes = attributes
168
- end
169
-
170
- def _unchange!
171
- @_changed = false
172
- end
173
-
174
- def each(&block)
175
- @_raw_attributes.each(&block)
176
- end
177
-
178
- def [](name)
179
- @_raw_attributes[name]
180
- end
181
-
182
- def []=(name, val)
183
- _validate_attribute(name, val)
184
- changed!
185
- @_raw_attributes[name] = val
186
- end
187
-
188
- def method_missing(method_name, *args, &block)
189
- if graph
190
- method_name_s = method_name.to_s
191
- singular_name = method_name_s.singularize
192
- node_edges = edges
193
- sid = to_sid
194
- camelized_singular = singular_name.camelize
195
-
196
- if method_name_s == singular_name
197
- # return one node
198
- node_edges.each do |edge|
199
- from_sid = edge.from_as_sid
200
- to_sid = edge.to_as_sid
201
- node = if from_sid[0] == camelized_singular && to_sid == sid
202
- edge.from
203
- elsif to_sid[0] == camelized_singular && from_sid == sid
204
- edge.to
205
- end
206
- return node if node
207
- end
208
- nil
209
- elsif method_name_s == method_name_s.pluralize
210
- # return all nodes
211
- nodes = []
212
- node_edges.each do |edge|
213
- from_sid = edge.from_as_sid
214
- to_sid = edge.to_as_sid
215
- node = if from_sid[0] == camelized_singular && to_sid == sid
216
- edge.from
217
- elsif to_sid[0] == camelized_singular && from_sid == sid
218
- edge.to
219
- end
220
- nodes << node if node
221
- end
222
- return nodes
223
- end
224
- else
225
- super(method_name, *args, &block)
226
- end
227
- end
228
- end # RUBY_ENGINE
229
- end
230
- end
231
- end
232
- end
@@ -1,13 +0,0 @@
1
- module LucidData
2
- module Query
3
- class Base
4
- include LucidData::Query::Mixin
5
-
6
- if RUBY_ENGINE != 'opal'
7
- def self.inherited(base)
8
- Isomorfeus.add_valid_data_class(base)
9
- end
10
- end
11
- end
12
- end
13
- end
@@ -1,83 +0,0 @@
1
- module LucidData
2
- module Query
3
- module Mixin
4
- def self.included(base)
5
- base.extend(LucidPropDeclaration::Mixin)
6
-
7
- if RUBY_ENGINE == 'opal'
8
- base.instance_exec do
9
- def execute(**props)
10
- props[:query_result_instance] = LucidData::QueryResult.new
11
- promise_execute(props) unless props[:query_result_instance].loaded?
12
- props[:query_result_instance]
13
- end
14
-
15
- def promise_execute(**props)
16
- query_result_instance = props.delete(:query_result_instance)
17
- query_result_instance = LucidData::QueryResult.new unless query_result_instance
18
- props.each_key do |prop_name|
19
- Isomorfeus.raise_error(message: "#{self.to_s} No such query prop declared: '#{prop_name}'!") unless declared_props.key?(prop_name)
20
- end
21
- props = validated_props(props)
22
- props[:query_result_instance_key] = query_result_instance.key
23
- Isomorfeus::Transport.promise_send_path( 'Isomorfeus::Data::Handler::Generic', self.name, :execute, props).then do |agent|
24
- if agent.processed
25
- agent.result
26
- else
27
- agent.processed = true
28
- if agent.response.key?(:error)
29
- Isomorfeus.raise_error(message: agent.response[:error])
30
- end
31
- query_result_instance._load_from_store!
32
- Isomorfeus.store.dispatch(type: 'DATA_LOAD', data: agent.full_response[:data])
33
- agent.result = query_result_instance
34
- end
35
- end
36
- end
37
-
38
- def execute_query(_); end
39
- end
40
- else
41
- unless base == LucidData::Node::Base || base == LucidData::Document::Base || base == LucidData::Vertex::Base
42
- Isomorfeus.add_valid_data_class(base)
43
- end
44
-
45
- base.instance_exec do
46
- def promise_execute(**props)
47
- instance = self.execute(**props)
48
- result_promise = Promise.new
49
- result_promise.resolve(instance)
50
- result_promise
51
- end
52
-
53
- def execute(**props)
54
- query_result_instance_key = props.delete(:query_result_instance_key)
55
- query_result = LucidData::QueryResult.new(key: query_result_instance_key)
56
- query_result.result_set = self.new(**props).instance_exec(&@_query_block)
57
- query_result
58
- end
59
-
60
- def execute_query(&block)
61
- @_query_block = block
62
- end
63
- end
64
-
65
- attr_reader :props
66
-
67
- def initialize(**props_hash)
68
- props_hash = self.class.validated_props(props_hash)
69
- @props = LucidProps.new(props_hash)
70
- end
71
-
72
- def current_user
73
- Isomorfeus.current_user
74
- end
75
-
76
- def pub_sub_client
77
- Isomorfeus.pub_sub_client
78
- end
79
- end
80
- end
81
- end
82
- end
83
- end
@@ -1,95 +0,0 @@
1
- module LucidData
2
- class QueryResult
3
- attr_reader :key
4
-
5
- def to_sid
6
- [@class_name, @key]
7
- end
8
-
9
- if RUBY_ENGINE == 'opal'
10
- def initialize(key: nil, result_set: {})
11
- @class_name = 'LucidData::QueryResult'
12
- @key = key ? key.to_s : self.object_id.to_s
13
- @result_set = result_set
14
- end
15
-
16
- def _load_from_store!
17
- @result_set = nil
18
- end
19
-
20
- def loaded?
21
- Redux.fetch_by_path(:data_state, @class_name, @key) ? true : false
22
- end
23
-
24
- def key?(k)
25
- if @result_set
26
- @result_set.key?(k)
27
- else
28
- stored_results = Redux.fetch_by_path(:data_state, @class_name, @key)
29
- return false unless stored_results
30
- `Object.hasOwnProperty(stored_results, k)`
31
- end
32
- end
33
- alias has_key? key?
34
-
35
- def result_set=(r)
36
- @result_set = r
37
- end
38
-
39
- def method_missing(accessor_name, *args, &block)
40
- sid = if @result_set
41
- @result_set[accessor_name]
42
- else
43
- stored_results = Redux.fetch_by_path(:data_state, @class_name, @key)
44
- stored_results.JS[accessor_name] if stored_results
45
- end
46
- Isomorfeus.raise_error(message: "#{@class_name}: no such thing '#{accessor_name}' in the results!") unless sid
47
- Isomorfeus.instance_from_sid(sid)
48
- end
49
- else
50
- def initialize(key: nil, result_set: {})
51
- @class_name = 'LucidData::QueryResult'
52
- @key = key ? key.to_s : self.object_id.to_s
53
- @result_set = result_set.nil? ? {} : result_set
54
- @result_set.transform_keys!(&:to_sym)
55
- end
56
-
57
- def loaded?
58
- @result_set.any?
59
- end
60
-
61
- def key?(k)
62
- @result_set.key?(k)
63
- end
64
- alias has_key? key?
65
-
66
- def result_set=(r)
67
- @result_set = r
68
- end
69
-
70
- def method_missing(accessor_name, *args, &block)
71
- Isomorfeus.raise_error(message: "#{@class_name}: no such thing '#{accessor_name}' in the results!") unless @result_set.key?(accessor_name)
72
- @result_set[accessor_name]
73
- end
74
-
75
- def to_transport
76
- sids_hash = {}
77
- @result_set.each do |key, value|
78
- sids_hash[key.to_s] = value.to_sid
79
- end
80
- { @class_name => { @key => sids_hash }}
81
- end
82
-
83
- def included_items_to_transport
84
- data_hash = {}
85
- @result_set.each_value do |value|
86
- data_hash.deep_merge!(value.to_transport)
87
- if value.respond_to?(:included_items_to_transport)
88
- data_hash.deep_merge!(value.included_items_to_transport)
89
- end
90
- end
91
- data_hash
92
- end
93
- end
94
- end
95
- end
@@ -1,13 +0,0 @@
1
- module LucidData
2
- module Vertex
3
- class Base
4
- include LucidData::Node::Mixin
5
-
6
- if RUBY_ENGINE != 'opal'
7
- def self.inherited(base)
8
- Isomorfeus.add_valid_data_class(base)
9
- end
10
- end
11
- end
12
- end
13
- end
@@ -1,9 +0,0 @@
1
- module LucidData
2
- module Vertex
3
- module Mixin
4
- def self.included(base)
5
- base.include(LucidData::Node::Mixin)
6
- end
7
- end
8
- end
9
- end
@@ -1,13 +0,0 @@
1
- module LucidArango
2
- module DocumentCollection
3
- class Base
4
- include LucidArango::DocumentCollection::Mixin
5
-
6
- if RUBY_ENGINE != 'opal'
7
- def self.inherited(base)
8
- Isomorfeus.add_valid_data_class(base)
9
- end
10
- end
11
- end
12
- end
13
- end
@@ -1,18 +0,0 @@
1
- module LucidArango
2
- module DocumentCollection
3
- module Mixin
4
- def self.included(base)
5
- if RUBY_ENGINE != 'opal'
6
- unless base == LucidArango::DocumentCollection::Base
7
- Isomorfeus.add_valid_data_class(base)
8
- end
9
- end
10
-
11
- base.include(Enumerable)
12
- base.extend(LucidPropDeclaration::Mixin)
13
-
14
- # TODO implement, depends on arango-driver
15
- end
16
- end
17
- end
18
- end
@@ -1,13 +0,0 @@
1
- module LucidArango
2
- module Document
3
- class Base
4
- include LucidArango::Node::Mixin
5
-
6
- if RUBY_ENGINE != 'opal'
7
- def self.inherited(base)
8
- Isomorfeus.add_valid_data_class(base)
9
- end
10
- end
11
- end
12
- end
13
- end
@@ -1,9 +0,0 @@
1
- module LucidAranog
2
- module Document
3
- module Mixin
4
- def self.included(base)
5
- base.include(LucidArango::Node::Mixin)
6
- end
7
- end
8
- end
9
- end
@@ -1,13 +0,0 @@
1
- module LucidArango
2
- module Edge
3
- class Base
4
- include LucidArango::Edge::Mixin
5
-
6
- if RUBY_ENGINE != 'opal'
7
- def self.inherited(base)
8
- Isomorfeus.add_valid_data_class(base)
9
- end
10
- end
11
- end
12
- end
13
- end
@@ -1,18 +0,0 @@
1
- module LucidArango
2
- module Edge
3
- module Mixin
4
- def self.included(base)
5
- if RUBY_ENGINE != 'opal'
6
- unless base == LucidArango::Edge::Base
7
- Isomorfeus.add_valid_data_class(base)
8
- end
9
- end
10
-
11
- base.include(Enumerable)
12
- base.extend(LucidPropDeclaration::Mixin)
13
-
14
- # TODO implement, depends on arango-driver
15
- end
16
- end
17
- end
18
- end
@@ -1,13 +0,0 @@
1
- module LucidArango
2
- module EdgeCollection
3
- class Base
4
- include LucidArango::EdgeCollection::Mixin
5
-
6
- if RUBY_ENGINE != 'opal'
7
- def self.inherited(base)
8
- Isomorfeus.add_valid_data_class(base)
9
- end
10
- end
11
- end
12
- end
13
- end
@@ -1,18 +0,0 @@
1
- module LucidArango
2
- module EdgeCollection
3
- module Mixin
4
- def self.included(base)
5
- if RUBY_ENGINE != 'opal'
6
- unless base == LucidArango::EdgeCollection::Base
7
- Isomorfeus.add_valid_data_class(base)
8
- end
9
- end
10
-
11
- base.include(Enumerable)
12
- base.extend(LucidPropDeclaration::Mixin)
13
-
14
- # TODO implement, depends on arango-driver
15
- end
16
- end
17
- end
18
- end
@@ -1,13 +0,0 @@
1
- module LucidArango
2
- module Graph
3
- class Base
4
- include LucidArango::Graph::Mixin
5
-
6
- if RUBY_ENGINE != 'opal'
7
- def self.inherited(base)
8
- Isomorfeus.add_valid_data_class(base)
9
- end
10
- end
11
- end
12
- end
13
- end
@@ -1,18 +0,0 @@
1
- module LucidArango
2
- module Graph
3
- module Mixin
4
- def self.included(base)
5
- if RUBY_ENGINE != 'opal'
6
- unless base == LucidArango::Graph::Base
7
- Isomorfeus.add_valid_data_class(base)
8
- end
9
- end
10
-
11
- base.include(Enumerable)
12
- base.extend(LucidPropDeclaration::Mixin)
13
-
14
- # TODO implement, depends on arango-driver
15
- end
16
- end
17
- end
18
- end
@@ -1,13 +0,0 @@
1
- module LucidArango
2
- module Document
3
- class Base
4
- include LucidArango::Document::Mixin
5
-
6
- if RUBY_ENGINE != 'opal'
7
- def self.inherited(base)
8
- Isomorfeus.add_valid_data_class(base)
9
- end
10
- end
11
- end
12
- end
13
- end