hyper-resource 1.0.0.lap79 → 1.0.0.lap80
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/.gitignore +3 -0
- data/.yardopts +1 -0
- data/API.md +62 -0
- data/Gemfile +2 -0
- data/JSON_format.md +62 -0
- data/PubSub.md +20 -0
- data/README.md +2 -0
- data/Security.md +0 -0
- data/docs/HyperRecord/ClassMethods.html +2969 -0
- data/docs/HyperRecord/ClientInstanceMethods.html +1833 -0
- data/docs/HyperRecord/Collection.html +564 -0
- data/docs/HyperRecord/DummyValue.html +384 -0
- data/docs/HyperRecord/PubSub/ClassMethods.html +2047 -0
- data/docs/HyperRecord/PubSub.html +1679 -0
- data/docs/HyperRecord/ServerClassMethods.html +697 -0
- data/docs/HyperRecord.html +119 -0
- data/docs/Hyperloop/Resource/ClientDrivers.html +352 -0
- data/docs/Hyperloop/Resource/HTTP.html +1795 -0
- data/docs/Hyperloop/Resource/MethodsController.html +479 -0
- data/docs/Hyperloop/Resource/PropertiesController.html +225 -0
- data/docs/Hyperloop/Resource/PubSub/ClassMethods.html +105 -0
- data/docs/Hyperloop/Resource/PubSub.html +1210 -0
- data/docs/Hyperloop/Resource/RelationsController.html +529 -0
- data/docs/Hyperloop/Resource/ScopesController.html +380 -0
- data/docs/Hyperloop/Resource/SecurityError.html +124 -0
- data/docs/Hyperloop/Resource/SecurityGuards/ClassMethods.html +226 -0
- data/docs/Hyperloop/Resource/SecurityGuards.html +299 -0
- data/docs/Hyperloop/Resource.html +135 -0
- data/docs/Hyperloop.html +186 -0
- data/docs/_index.html +302 -0
- data/docs/class_list.html +51 -0
- data/docs/css/common.css +1 -0
- data/docs/css/full_list.css +58 -0
- data/docs/css/style.css +496 -0
- data/docs/file.API.html +138 -0
- data/docs/file.JSON_format.html +134 -0
- data/docs/file.PubSub.html +86 -0
- data/docs/file.README.html +192 -0
- data/docs/file_list.html +71 -0
- data/docs/frames.html +17 -0
- data/docs/index.html +192 -0
- data/docs/js/app.js +292 -0
- data/docs/js/full_list.js +216 -0
- data/docs/js/jquery.js +4 -0
- data/docs/method_list.html +1115 -0
- data/docs/top-level-namespace.html +110 -0
- data/hyper-resource.gemspec +19 -18
- data/lib/hyper_record/class_methods.rb +186 -3
- data/lib/hyper_record/client_instance_methods.rb +68 -3
- data/lib/hyper_record/collection.rb +19 -4
- data/lib/hyper_record/pub_sub.rb +92 -12
- data/lib/hyper_record/server_class_methods.rb +15 -0
- data/lib/hyperloop/resource/client_drivers.rb +2 -0
- data/lib/hyperloop/resource/http.rb +33 -22
- data/lib/hyperloop/resource/pub_sub.rb +2 -0
- data/lib/hyperloop/resource/version.rb +1 -1
- metadata +61 -2
@@ -0,0 +1,110 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
|
+
<title>
|
7
|
+
Top Level Namespace
|
8
|
+
|
9
|
+
— Documentation by YARD 0.9.13
|
10
|
+
|
11
|
+
</title>
|
12
|
+
|
13
|
+
<link rel="stylesheet" href="css/style.css" type="text/css" charset="utf-8" />
|
14
|
+
|
15
|
+
<link rel="stylesheet" href="css/common.css" type="text/css" charset="utf-8" />
|
16
|
+
|
17
|
+
<script type="text/javascript" charset="utf-8">
|
18
|
+
pathId = "";
|
19
|
+
relpath = '';
|
20
|
+
</script>
|
21
|
+
|
22
|
+
|
23
|
+
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
|
24
|
+
|
25
|
+
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
|
26
|
+
|
27
|
+
|
28
|
+
</head>
|
29
|
+
<body>
|
30
|
+
<div class="nav_wrap">
|
31
|
+
<iframe id="nav" src="class_list.html?1"></iframe>
|
32
|
+
<div id="resizer"></div>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div id="main" tabindex="-1">
|
36
|
+
<div id="header">
|
37
|
+
<div id="menu">
|
38
|
+
|
39
|
+
<a href="_index.html">Index</a> »
|
40
|
+
|
41
|
+
|
42
|
+
<span class="title">Top Level Namespace</span>
|
43
|
+
|
44
|
+
</div>
|
45
|
+
|
46
|
+
<div id="search">
|
47
|
+
|
48
|
+
<a class="full_list_link" id="class_list_link"
|
49
|
+
href="class_list.html">
|
50
|
+
|
51
|
+
<svg width="24" height="24">
|
52
|
+
<rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
|
53
|
+
<rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
|
54
|
+
<rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
|
55
|
+
</svg>
|
56
|
+
</a>
|
57
|
+
|
58
|
+
</div>
|
59
|
+
<div class="clear"></div>
|
60
|
+
</div>
|
61
|
+
|
62
|
+
<div id="content"><h1>Top Level Namespace
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
</h1>
|
67
|
+
<div class="box_info">
|
68
|
+
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
</div>
|
80
|
+
|
81
|
+
<h2>Defined Under Namespace</h2>
|
82
|
+
<p class="children">
|
83
|
+
|
84
|
+
|
85
|
+
<strong class="modules">Modules:</strong> <span class='object_link'><a href="HyperRecord.html" title="HyperRecord (module)">HyperRecord</a></span>, <span class='object_link'><a href="Hyperloop.html" title="Hyperloop (module)">Hyperloop</a></span>
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
</p>
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
</div>
|
101
|
+
|
102
|
+
<div id="footer">
|
103
|
+
Generated on Tue Jun 5 23:13:52 2018 by
|
104
|
+
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
105
|
+
0.9.13 (ruby-2.5.1).
|
106
|
+
</div>
|
107
|
+
|
108
|
+
</div>
|
109
|
+
</body>
|
110
|
+
</html>
|
data/hyper-resource.gemspec
CHANGED
@@ -1,29 +1,30 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative 'lib/hyperloop/resource/version'
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
|
-
s.name =
|
4
|
+
s.name = 'hyper-resource'
|
5
5
|
s.version = Hyperloop::Resource::VERSION
|
6
|
-
s.author =
|
7
|
-
s.email =
|
8
|
-
s.homepage =
|
9
|
-
s.summary =
|
6
|
+
s.author = 'Jan Biedermann'
|
7
|
+
s.email = 'jan@kursator.de'
|
8
|
+
s.homepage = 'https://github.com/janbiedermann/hyper-resource'
|
9
|
+
s.summary = 'Transparent Opal Ruby Data/Resource Access from the browser for Ruby-Hyperloop'
|
10
10
|
s.description = "Write Browser Apps that transparently access server side resources like 'MyModel.first_name', with ease"
|
11
11
|
|
12
12
|
s.files = `git ls-files`.split("\n")
|
13
13
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
|
-
s.require_paths = [
|
14
|
+
s.require_paths = ['lib']
|
15
15
|
|
16
|
-
s.add_runtime_dependency
|
17
|
-
s.add_runtime_dependency
|
16
|
+
s.add_runtime_dependency 'opal', '~> 0.11.0'
|
17
|
+
s.add_runtime_dependency 'opal-activesupport', '~> 0.3.1'
|
18
18
|
s.add_runtime_dependency 'hyper-component' , '~> 1.0.0.lap27'
|
19
19
|
s.add_runtime_dependency 'hyper-store' , '~> 1.0.0.lap27'
|
20
|
-
s.add_runtime_dependency
|
21
|
-
s.add_development_dependency
|
22
|
-
s.add_development_dependency
|
23
|
-
s.add_development_dependency
|
24
|
-
s.add_development_dependency
|
25
|
-
s.add_development_dependency
|
26
|
-
s.add_development_dependency
|
27
|
-
s.add_development_dependency
|
28
|
-
s.add_development_dependency
|
20
|
+
s.add_runtime_dependency 'hyperloop-config', '~> 1.0.0.lap27'
|
21
|
+
s.add_development_dependency 'hyperloop', '~> 1.0.0.lap27'
|
22
|
+
s.add_development_dependency 'hyper-spec', '~> 1.0.0.lap27'
|
23
|
+
s.add_development_dependency 'listen'
|
24
|
+
s.add_development_dependency 'rake', '>= 11.3.0'
|
25
|
+
s.add_development_dependency 'rails', '>= 5.1.0'
|
26
|
+
s.add_development_dependency 'redis'
|
27
|
+
s.add_development_dependency 'rspec-rails'
|
28
|
+
s.add_development_dependency 'sqlite3'
|
29
|
+
s.add_development_dependency 'yard', '~> 0.9.13'
|
29
30
|
end
|
@@ -1,6 +1,10 @@
|
|
1
1
|
module HyperRecord
|
2
2
|
module ClassMethods
|
3
3
|
|
4
|
+
# create a new instance of current HyperRecord class or return a exisitng one if a id in the hash is given
|
5
|
+
#
|
6
|
+
# @param record_hash [Hash] optional data for the record
|
7
|
+
# @return [HyperRecord] the new instance or the existing one for a given id
|
4
8
|
def new(record_hash = {})
|
5
9
|
if record_hash.has_key?(:id)
|
6
10
|
if _record_cache.has_key?(record_hash[:id].to_s)
|
@@ -15,6 +19,9 @@ module HyperRecord
|
|
15
19
|
super(record_hash)
|
16
20
|
end
|
17
21
|
|
22
|
+
# all records of current HyperRecord class
|
23
|
+
#
|
24
|
+
# @return [HyperRecord::Collection]
|
18
25
|
def all
|
19
26
|
_register_class_observer
|
20
27
|
if _class_fetch_states.has_key?(:all) && 'fi'.include?(_class_fetch_states[:all]) # if f_etched or i_n progress of fetching
|
@@ -26,6 +33,10 @@ module HyperRecord
|
|
26
33
|
HyperRecord::Collection.new
|
27
34
|
end
|
28
35
|
|
36
|
+
# all records of current HyperRecord class
|
37
|
+
#
|
38
|
+
# @return [Promise] on success the .then block will receive a [HyperRecord::Collection] as arg
|
39
|
+
# on failure the .fail block will receive the HTTP response object as arg
|
29
40
|
def promise_all
|
30
41
|
_class_fetch_states[:all] = 'i'
|
31
42
|
_promise_get("#{resource_base_uri}.json?timestamp=#{`Date.now() + Math.random()`}").then do |response|
|
@@ -40,6 +51,17 @@ module HyperRecord
|
|
40
51
|
end
|
41
52
|
end
|
42
53
|
|
54
|
+
# DSL macro to declare a belongs_to relationship
|
55
|
+
# options are for the server side ORM, on the client side options are ignored
|
56
|
+
#
|
57
|
+
# This macro defines additional methods:
|
58
|
+
# promise_[name]
|
59
|
+
# return [Promise] on success the .then block will receive a [HyperRecord::Collection] as arg
|
60
|
+
# on failure the .fail block will receive the HTTP response object as arg
|
61
|
+
#
|
62
|
+
# @param direction [String, Symbol] for ORMs like Neo4j: the direction of the graph edge, for ORMs like ActiveRecord: the name of the relation
|
63
|
+
# @param name [String, Symbol, Hash] for ORMs like Neo4j: the name of the relation, for ORMs like ActiveRecord: further options
|
64
|
+
# @param options [Hash] further options for ORMs like Neo4j
|
43
65
|
def belongs_to(direction, name = nil, options = { type: nil })
|
44
66
|
if name.is_a?(Hash)
|
45
67
|
options.merge(name)
|
@@ -52,10 +74,15 @@ module HyperRecord
|
|
52
74
|
name = direction
|
53
75
|
end
|
54
76
|
reflections[name] = { direction: direction, type: options[:type], kind: :belongs_to }
|
77
|
+
|
55
78
|
define_method("promise_#{name}") do
|
56
79
|
@fetch_states[name] = 'i'
|
57
80
|
self.class._promise_get("#{self.class.resource_base_uri}/#{self.id}/relations/#{name}.json?timestamp=#{`Date.now() + Math.random()`}").then do |response|
|
58
|
-
@relations[name] =
|
81
|
+
@relations[name] = if response.json[self.class.to_s.underscore][name]
|
82
|
+
self.class._convert_json_hash_to_record(response.json[self.class.to_s.underscore][name])
|
83
|
+
else
|
84
|
+
nil
|
85
|
+
end
|
59
86
|
@fetch_states[name] = 'f'
|
60
87
|
_notify_observers
|
61
88
|
@relations[name]
|
@@ -65,6 +92,9 @@ module HyperRecord
|
|
65
92
|
response
|
66
93
|
end
|
67
94
|
end
|
95
|
+
# @!method [name] get records of the relation
|
96
|
+
# @return [HyperRecord::Collection] either a empty one, if the data has not been fetched yet, or the
|
97
|
+
# collection with the real data, if it has been fetched already
|
68
98
|
define_method(name) do
|
69
99
|
_register_observer
|
70
100
|
if @fetch_states.has_key?(name) && 'fi'.include?(@fetch_states[name])
|
@@ -76,8 +106,11 @@ module HyperRecord
|
|
76
106
|
@relations[name]
|
77
107
|
end
|
78
108
|
end
|
109
|
+
# @!method update_[name] mark internal structures so that the relation data is updated once it is requested again
|
110
|
+
# @return nil
|
79
111
|
define_method("update_#{name}") do
|
80
112
|
@fetch_states[name] = 'u'
|
113
|
+
nil
|
81
114
|
end
|
82
115
|
# TODO
|
83
116
|
# define_method("#{name}=") do |arg|
|
@@ -88,16 +121,29 @@ module HyperRecord
|
|
88
121
|
# end
|
89
122
|
end
|
90
123
|
|
124
|
+
# create a new instance of current HyperRecord class and save it to the db
|
125
|
+
#
|
126
|
+
# @param record_hash [Hash] optional data for the record
|
127
|
+
# @return [HyperRecord] the new instance
|
91
128
|
def create(record_hash = {})
|
92
129
|
record = new(record_hash)
|
93
130
|
record.save
|
94
131
|
end
|
95
132
|
|
133
|
+
# create a new instance of current HyperRecord class and save it to the db
|
134
|
+
#
|
135
|
+
# @param record_hash [Hash] optional data for the record
|
136
|
+
# @return [Promise] on success the .then block will receive the new HyperRecord instance as arg
|
137
|
+
# on failure the .fail block will receive the HTTP response object as arg
|
96
138
|
def promise_create(record_hash = {})
|
97
139
|
record = new(record_hash)
|
98
140
|
record.promise_save
|
99
141
|
end
|
100
142
|
|
143
|
+
# find a existing instance of current HyperRecord class
|
144
|
+
#
|
145
|
+
# @param id [String] id of the record to find
|
146
|
+
# @return [HyperRecord]
|
101
147
|
def find(id)
|
102
148
|
sid = id.to_s
|
103
149
|
return nil if sid == ''
|
@@ -117,6 +163,11 @@ module HyperRecord
|
|
117
163
|
record_in_progress
|
118
164
|
end
|
119
165
|
|
166
|
+
# find a existing instance of current HyperRecord class
|
167
|
+
#
|
168
|
+
# @param id [String] id of the record to find
|
169
|
+
# @return [Promise] on success the .then block will receive the new HyperRecord instance as arg
|
170
|
+
# on failure the .fail block will receive the HTTP response object as arg
|
120
171
|
def promise_find(id)
|
121
172
|
sid = id.to_s
|
122
173
|
record_in_progress = if _record_cache.has_key?(sid)
|
@@ -146,6 +197,14 @@ module HyperRecord
|
|
146
197
|
# end
|
147
198
|
# end
|
148
199
|
|
200
|
+
# DSL macro to declare a has_and_belongs_many relationship
|
201
|
+
# options are for the server side ORM, on the client side options are ignored
|
202
|
+
#
|
203
|
+
# @param direction [String] or [Symbol] for ORMs like Neo4j: the direction of the graph edge, for ORMs like ActiveRecord: the name of the relation
|
204
|
+
# @param name [String] or [Symbol] or [Hash] for ORMs like Neo4j: the name of the relation, for ORMs like ActiveRecord: further options
|
205
|
+
# @param options [Hash] further options for ORMs like Neo4j
|
206
|
+
#
|
207
|
+
# This macro defines additional methods:
|
149
208
|
def has_and_belongs_to_many(direction, name = nil, options = { type: nil })
|
150
209
|
if name.is_a?(Hash)
|
151
210
|
options.merge(name)
|
@@ -158,6 +217,9 @@ module HyperRecord
|
|
158
217
|
name = direction
|
159
218
|
end
|
160
219
|
reflections[name] = { direction: direction, type: options[:type], kind: :has_and_belongs_to_many }
|
220
|
+
# @!method promise_[name]
|
221
|
+
# @return [Promise] on success the .then block will receive a [HyperRecord::Collection] as arg
|
222
|
+
# on failure the .fail block will receive the HTTP response object as arg
|
161
223
|
define_method("promise_#{name}") do
|
162
224
|
@fetch_states[name] = 'i'
|
163
225
|
self.class._promise_get("#{self.class.resource_base_uri}/#{self.id}/relations/#{name}.json?timestamp=#{`Date.now() + Math.random()`}").then do |response|
|
@@ -172,6 +234,9 @@ module HyperRecord
|
|
172
234
|
response
|
173
235
|
end
|
174
236
|
end
|
237
|
+
# @!method [name] get records of the relation
|
238
|
+
# @return [HyperRecord::Collection] either a empty one, if the data has not been fetched yet, or the
|
239
|
+
# collection with the real data, if it has been fetched already
|
175
240
|
define_method(name) do
|
176
241
|
_register_observer
|
177
242
|
if @fetch_states.has_key?(name) && 'fi'.include?(@fetch_states[name])
|
@@ -183,8 +248,11 @@ module HyperRecord
|
|
183
248
|
@relations[name]
|
184
249
|
end
|
185
250
|
end
|
251
|
+
# @!method update_[name] mark internal structures so that the relation data is updated once it is requested again
|
252
|
+
# @return nil
|
186
253
|
define_method("update_#{name}") do
|
187
254
|
@fetch_states[name] = 'u'
|
255
|
+
nil
|
188
256
|
end
|
189
257
|
# TODO
|
190
258
|
# define_method("#{name}=") do |arg|
|
@@ -202,6 +270,14 @@ module HyperRecord
|
|
202
270
|
# end
|
203
271
|
end
|
204
272
|
|
273
|
+
# DSL macro to declare a has_many relationship
|
274
|
+
# options are for the server side ORM, on the client side options are ignored
|
275
|
+
#
|
276
|
+
# @param direction [String] or [Symbol] for ORMs like Neo4j: the direction of the graph edge, for ORMs like ActiveRecord: the name of the relation
|
277
|
+
# @param name [String] or [Symbol] or [Hash] for ORMs like Neo4j: the name of the relation, for ORMs like ActiveRecord: further options
|
278
|
+
# @param options [Hash] further options for ORMs like Neo4j
|
279
|
+
#
|
280
|
+
# This macro defines additional methods:
|
205
281
|
def has_many(direction, name = nil, options = { type: nil })
|
206
282
|
if name.is_a?(Hash)
|
207
283
|
options.merge(name)
|
@@ -214,6 +290,9 @@ module HyperRecord
|
|
214
290
|
name = direction
|
215
291
|
end
|
216
292
|
reflections[name] = { direction: direction, type: options[:type], kind: :has_many }
|
293
|
+
# @!method promise_[name]
|
294
|
+
# @return [Promise] on success the .then block will receive a [HyperRecord::Collection] as arg
|
295
|
+
# on failure the .fail block will receive the HTTP response object as arg
|
217
296
|
define_method("promise_#{name}") do
|
218
297
|
@fetch_states[name] = 'i'
|
219
298
|
self.class._promise_get("#{self.class.resource_base_uri}/#{self.id}/relations/#{name}.json?timestamp=#{`Date.now() + Math.random()`}").then do |response|
|
@@ -228,6 +307,9 @@ module HyperRecord
|
|
228
307
|
response
|
229
308
|
end
|
230
309
|
end
|
310
|
+
# @!method [name] get records of the relation
|
311
|
+
# @return [HyperRecord::Collection] either a empty one, if the data has not been fetched yet, or the
|
312
|
+
# collection with the real data, if it has been fetched already
|
231
313
|
define_method(name) do
|
232
314
|
_register_observer
|
233
315
|
if @fetch_states.has_key?(name) && 'fi'.include?(@fetch_states[name])
|
@@ -239,8 +321,11 @@ module HyperRecord
|
|
239
321
|
@relations[name]
|
240
322
|
end
|
241
323
|
end
|
324
|
+
# @!method update_[name] mark internal structures so that the relation data is updated once it is requested again
|
325
|
+
# @return nil
|
242
326
|
define_method("update_#{name}") do
|
243
327
|
@fetch_states[name] = 'u'
|
328
|
+
nil
|
244
329
|
end
|
245
330
|
# define_method("#{name}=") do |arg|
|
246
331
|
# _register_observer
|
@@ -257,6 +342,14 @@ module HyperRecord
|
|
257
342
|
# end
|
258
343
|
end
|
259
344
|
|
345
|
+
# DSL macro to declare a has_one relationship
|
346
|
+
# options are for the server side ORM, on the client side options are ignored
|
347
|
+
#
|
348
|
+
# @param direction [String] or [Symbol] for ORMs like Neo4j: the direction of the graph edge, for ORMs like ActiveRecord: the name of the relation
|
349
|
+
# @param name [String] or [Symbol] or [Hash] for ORMs like Neo4j: the name of the relation, for ORMs like ActiveRecord: further options
|
350
|
+
# @param options [Hash] further options for ORMs like Neo4j
|
351
|
+
#
|
352
|
+
# This macro defines additional methods:
|
260
353
|
def has_one(direction, name, options = { type: nil })
|
261
354
|
if name.is_a?(Hash)
|
262
355
|
options.merge(name)
|
@@ -269,6 +362,9 @@ module HyperRecord
|
|
269
362
|
name = direction
|
270
363
|
end
|
271
364
|
reflections[name] = { direction: direction, type: options[:type], kind: :has_one }
|
365
|
+
# @!method promise_[name]
|
366
|
+
# @return [Promise] on success the .then block will receive a [HyperRecord::Collection] as arg
|
367
|
+
# on failure the .fail block will receive the HTTP response object as arg
|
272
368
|
define_method("promise_#{name}") do
|
273
369
|
@fetch_states[name] = 'i'
|
274
370
|
self.class._promise_get("#{self.class.resource_base_uri}/#{self.id}/relations/#{name}.json?timestamp=#{`Date.now() + Math.random()`}").then do |response|
|
@@ -282,6 +378,9 @@ module HyperRecord
|
|
282
378
|
response
|
283
379
|
end
|
284
380
|
end
|
381
|
+
# @!method [name] get records of the relation
|
382
|
+
# @return [HyperRecord::Collection] either a empty one, if the data has not been fetched yet, or the
|
383
|
+
# collection with the real data, if it has been fetched already
|
285
384
|
define_method(name) do
|
286
385
|
_register_observer
|
287
386
|
if @fetch_states.has_key?(name) && 'fi'.include?(@fetch_states[name])
|
@@ -293,8 +392,11 @@ module HyperRecord
|
|
293
392
|
@relations[name]
|
294
393
|
end
|
295
394
|
end
|
395
|
+
# @!method update_[name] mark internal structures so that the relation data is updated once it is requested again
|
396
|
+
# @return nil
|
296
397
|
define_method("update_#{name}") do
|
297
398
|
@fetch_states[name] = 'u'
|
399
|
+
nil
|
298
400
|
end
|
299
401
|
# define_method("#{name}=") do |arg|
|
300
402
|
# _register_observer
|
@@ -304,13 +406,22 @@ module HyperRecord
|
|
304
406
|
# end
|
305
407
|
end
|
306
408
|
|
409
|
+
# check if a record of current HyperRecord class has been cached already
|
410
|
+
# @param id [String]
|
307
411
|
def record_cached?(id)
|
308
412
|
_record_cache.has_key?(id.to_s)
|
309
413
|
end
|
310
414
|
|
415
|
+
# declare a property (attribute) for the current HyperRecord class
|
416
|
+
# @param name [String] or [Symbol]
|
417
|
+
# @param options [Hash] following keys are known:
|
418
|
+
# default: a default value to present during render if no other value is known
|
419
|
+
# type: type for a HyperRecord::DummyValue in case no default or other value is known
|
420
|
+
#
|
421
|
+
# This macro defines additional methods:
|
311
422
|
def property(name, options = {})
|
312
|
-
# ToDo options maybe, ddefault value? type check?
|
313
423
|
_property_options[name] = options
|
424
|
+
# @!method [name] a getter for the property
|
314
425
|
define_method(name) do
|
315
426
|
_register_observer
|
316
427
|
if @properties[:id]
|
@@ -335,18 +446,32 @@ module HyperRecord
|
|
335
446
|
end
|
336
447
|
end
|
337
448
|
end
|
449
|
+
# @!method [name]= a setter for the property
|
450
|
+
# @param value the new value for the property
|
338
451
|
define_method("#{name}=") do |value|
|
339
452
|
_register_observer
|
340
453
|
@changed_properties[name] = value
|
341
454
|
end
|
342
455
|
end
|
343
456
|
|
457
|
+
# introspect on current HyperRecord class
|
458
|
+
# @return [Hash]
|
344
459
|
def reflections
|
345
460
|
@reflections ||= {}
|
346
461
|
end
|
347
462
|
|
463
|
+
# macro define rest_class_methods, RPC on class level of current HyperRecord class
|
464
|
+
#
|
465
|
+
# @param name [Symbol] name of method
|
466
|
+
# @param options [Hash] with known keys:
|
467
|
+
# default_result: result to present during render during method call in progress
|
468
|
+
#
|
469
|
+
# This macro defines additional methods:
|
348
470
|
def rest_class_method(name, options = { default_result: '...' })
|
349
471
|
rest_class_methods[name] = options
|
472
|
+
# @!method promise_[name]
|
473
|
+
# @return [Promise] on success the .then block will receive the result of the RPC call as arg
|
474
|
+
# on failure the .fail block will receive the HTTP response object as arg
|
350
475
|
define_singleton_method("promise_#{name}") do |*args|
|
351
476
|
name_args = _name_args(name, *args)
|
352
477
|
_class_fetch_states[name_args] = 'i'
|
@@ -362,6 +487,8 @@ module HyperRecord
|
|
362
487
|
response
|
363
488
|
end
|
364
489
|
end
|
490
|
+
# @!method [name]
|
491
|
+
# @return result either the default_result ass specified in the options or the real result if the RPC call already finished
|
365
492
|
define_singleton_method(name) do |*args|
|
366
493
|
name_args = _name_args(name, *args)
|
367
494
|
_register_class_observer
|
@@ -371,12 +498,25 @@ module HyperRecord
|
|
371
498
|
end
|
372
499
|
rest_class_methods[name_args][:result]
|
373
500
|
end
|
501
|
+
# @!method update_[name] mark internal structures so that the method is called again once it is requested again
|
502
|
+
# @return nil
|
374
503
|
define_singleton_method("update_#{name}") do |*args|
|
375
504
|
_class_fetch_states[_name_args(name, *args)] = 'u'
|
505
|
+
nil
|
376
506
|
end
|
377
507
|
end
|
378
508
|
|
509
|
+
# macro define rest_class_methods, RPC on instance level of a record of current HyperRecord class
|
510
|
+
#
|
511
|
+
# @param name [Symbol] name of method
|
512
|
+
# @param options [Hash] with known keys:
|
513
|
+
# default_result: result to present during render during method call in progress
|
514
|
+
#
|
515
|
+
# This macro defines additional methods:
|
379
516
|
def rest_method(name, options = { default_result: '...' })
|
517
|
+
# @!method promise_[name]
|
518
|
+
# @return [Promise] on success the .then block will receive the result of the RPC call as arg
|
519
|
+
# on failure the .fail block will receive the HTTP response object as arg
|
380
520
|
define_method("promise_#{name}") do |*args|
|
381
521
|
name_args = self.class._name_args(name, *args)
|
382
522
|
@fetch_states[name_args] = 'i'
|
@@ -394,6 +534,8 @@ module HyperRecord
|
|
394
534
|
response
|
395
535
|
end
|
396
536
|
end
|
537
|
+
# @!method [name]
|
538
|
+
# @return result either the default_result ass specified in the options or the real result if the RPC call already finished
|
397
539
|
define_method(name) do |*args|
|
398
540
|
_register_observer
|
399
541
|
name_args = self.class._name_args(name, *args)
|
@@ -404,20 +546,37 @@ module HyperRecord
|
|
404
546
|
end
|
405
547
|
@rest_methods[name_args][:result]
|
406
548
|
end
|
549
|
+
# @!method update_[name] mark internal structures so that the method is called again once it is requested again
|
550
|
+
# @return nil
|
407
551
|
define_method("update_#{name}") do |*args|
|
408
552
|
@fetch_states[self.class._name_args(name, *args)] = 'u'
|
553
|
+
nil
|
409
554
|
end
|
410
555
|
end
|
411
556
|
|
557
|
+
# introspect on available rest_class_methods
|
558
|
+
# @return [Hash]
|
412
559
|
def rest_class_methods
|
413
560
|
@rest_class_methods ||= {}
|
414
561
|
end
|
415
562
|
|
563
|
+
# get the resource base uri that is used for api calls, used internally
|
564
|
+
# @return [String]
|
416
565
|
def resource_base_uri
|
417
566
|
@resource ||= "#{Hyperloop::Resource::ClientDrivers.opts[:resource_api_base_path]}/#{self.to_s.underscore.pluralize}"
|
418
567
|
end
|
419
568
|
|
569
|
+
# DSL macro to declare a scope
|
570
|
+
# options are for the server side ORM, on the client side options are ignored
|
571
|
+
#
|
572
|
+
# @param name [String] or [Symbol] the name of the relation
|
573
|
+
# @param options [Hash] further options
|
574
|
+
#
|
575
|
+
# This macro defines additional methods:
|
420
576
|
def scope(name, options)
|
577
|
+
# @!method promise_[name]
|
578
|
+
# @return [Promise] on success the .then block will receive a [HyperRecord::Collection] as arg
|
579
|
+
# on failure the .fail block will receive the HTTP response object as arg
|
421
580
|
define_singleton_method("promise_#{name}") do |*args|
|
422
581
|
name_args = _name_args(name, *args)
|
423
582
|
_class_fetch_states[name_args] = 'i'
|
@@ -432,6 +591,9 @@ module HyperRecord
|
|
432
591
|
response
|
433
592
|
end
|
434
593
|
end
|
594
|
+
# @!method [name] get records of the scope
|
595
|
+
# @return [HyperRecord::Collection] either a empty one, if the data has not been fetched yet, or the
|
596
|
+
# collection with the real data, if it has been fetched already
|
435
597
|
define_singleton_method(name) do |*args|
|
436
598
|
name_args = _name_args(name, *args)
|
437
599
|
scopes[name_args] = HyperRecord::Collection.new unless scopes.has_key?(name_args)
|
@@ -441,17 +603,23 @@ module HyperRecord
|
|
441
603
|
end
|
442
604
|
scopes[name_args]
|
443
605
|
end
|
606
|
+
# @!method update_[name] mark internal structures so that the scope data is updated once it is requested again
|
607
|
+
# @return nil
|
444
608
|
define_singleton_method("update_#{name}") do |*args|
|
445
609
|
_class_fetch_states[_name_args(name, *args)] = 'u'
|
610
|
+
nil
|
446
611
|
end
|
447
612
|
end
|
448
613
|
|
614
|
+
# introspect on available scopes
|
615
|
+
# @return [Hash]
|
449
616
|
def scopes
|
450
617
|
@scopes ||= {}
|
451
618
|
end
|
452
619
|
|
453
|
-
|
620
|
+
# internal, should not be used in application code
|
454
621
|
|
622
|
+
# @private
|
455
623
|
def _convert_array_to_collection(array, record = nil, relation_name = nil)
|
456
624
|
res = array.map do |record_hash|
|
457
625
|
_convert_json_hash_to_record(record_hash)
|
@@ -459,6 +627,7 @@ module HyperRecord
|
|
459
627
|
HyperRecord::Collection.new(res, record, relation_name)
|
460
628
|
end
|
461
629
|
|
630
|
+
# @private
|
462
631
|
def _convert_json_hash_to_record(record_hash)
|
463
632
|
return nil if !record_hash
|
464
633
|
klass_key = record_hash.keys.first
|
@@ -479,21 +648,25 @@ module HyperRecord
|
|
479
648
|
end
|
480
649
|
end
|
481
650
|
|
651
|
+
# @private
|
482
652
|
def _class_fetch_states
|
483
653
|
@_class_fetch_states ||= { all: 'n' }
|
484
654
|
@_class_fetch_states
|
485
655
|
end
|
486
656
|
|
657
|
+
# @private
|
487
658
|
def _class_observers
|
488
659
|
@_class_observers ||= Set.new
|
489
660
|
@_class_observers
|
490
661
|
end
|
491
662
|
|
663
|
+
# @private
|
492
664
|
def _class_state_key
|
493
665
|
@_class_state_key ||= self.to_s
|
494
666
|
@_class_state_key
|
495
667
|
end
|
496
668
|
|
669
|
+
# @private
|
497
670
|
def _name_args(name, *args)
|
498
671
|
if args.size > 0
|
499
672
|
"#{name}_#{args.to_json}"
|
@@ -502,6 +675,7 @@ module HyperRecord
|
|
502
675
|
end
|
503
676
|
end
|
504
677
|
|
678
|
+
# @private
|
505
679
|
def _promise_find(id, record_in_progress)
|
506
680
|
_class_fetch_states["record_#{id}"] = 'i'
|
507
681
|
_promise_get("#{resource_base_uri}/#{id}.json?timestamp=#{`Date.now() + Math.random()`}").then do |response|
|
@@ -523,6 +697,7 @@ module HyperRecord
|
|
523
697
|
end
|
524
698
|
end
|
525
699
|
|
700
|
+
# @private
|
526
701
|
def _notify_class_observers
|
527
702
|
_class_observers.each do |observer|
|
528
703
|
React::State.set_state(observer, _class_state_key, `Date.now() + Math.random()`)
|
@@ -530,10 +705,12 @@ module HyperRecord
|
|
530
705
|
_class_observers = Set.new
|
531
706
|
end
|
532
707
|
|
708
|
+
# @private
|
533
709
|
def _promise_get(uri)
|
534
710
|
Hyperloop::Resource::HTTP.get(uri, headers: { 'Content-Type' => 'application/json' })
|
535
711
|
end
|
536
712
|
|
713
|
+
# @private
|
537
714
|
def _promise_get_or_patch(uri, *args)
|
538
715
|
if args && args.size > 0
|
539
716
|
payload = { params: args }
|
@@ -547,30 +724,36 @@ module HyperRecord
|
|
547
724
|
end
|
548
725
|
end
|
549
726
|
|
727
|
+
# @private
|
550
728
|
def _promise_delete(uri)
|
551
729
|
Hyperloop::Resource::HTTP.delete(uri, headers: { 'Content-Type' => 'application/json' })
|
552
730
|
end
|
553
731
|
|
732
|
+
# @private
|
554
733
|
def _promise_patch(uri, payload)
|
555
734
|
Hyperloop::Resource::HTTP.patch(uri, payload: payload,
|
556
735
|
headers: { 'Content-Type' => 'application/json' },
|
557
736
|
dataType: :json)
|
558
737
|
end
|
559
738
|
|
739
|
+
# @private
|
560
740
|
def _promise_post(uri, payload)
|
561
741
|
Hyperloop::Resource::HTTP.post(uri, payload: payload,
|
562
742
|
headers: { 'Content-Type' => 'application/json' },
|
563
743
|
dataType: :json)
|
564
744
|
end
|
565
745
|
|
746
|
+
# @private
|
566
747
|
def _property_options
|
567
748
|
@property_options ||= {}
|
568
749
|
end
|
569
750
|
|
751
|
+
# @private
|
570
752
|
def _record_cache
|
571
753
|
@record_cache ||= {}
|
572
754
|
end
|
573
755
|
|
756
|
+
# @private
|
574
757
|
def _register_class_observer
|
575
758
|
observer = React::State.current_observer
|
576
759
|
if observer
|