hyper-model 1.0.alpha1.2 → 1.0.alpha1.3

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: 87c3f5488b0d7290f9fd974234351fae079e3830db6e57e953b54f9063ae41ab
4
- data.tar.gz: cfd1b544e23337620f978df7bb625503bfd2b6cdaa832f874e4dd94a15f02e34
3
+ metadata.gz: 071e8cc562ebddf1c0a260587a123d91db9f2a7c52d43b06fcf063079d66129f
4
+ data.tar.gz: 4cb7539129b7367f3156c0726ac3ed164e1db391f7806457253d303e9940941c
5
5
  SHA512:
6
- metadata.gz: e17c81b272167cd39b48b1c63fb7c451100966ede28e886ad2a8e0ddf328a961cb01dd63af6341fc166e8095fed23d0d13e98d589e873fd39d205168851e5cac
7
- data.tar.gz: bb7a6021e96284469580667b58304e3aaa41ae3fdae4196f14123a09d44be53908dbf4ea0165d5edd903132f84a9f8d144629d6292eea55063681a814e8e908b
6
+ metadata.gz: 2c1bcd8fee396593e2f31d072f35cbf88467be2b02c198d523c052b67a211d9fea4501ca86c4f0a388cee35bc34f4ac9156147a13aac9aec4842616a5c3c1772
7
+ data.tar.gz: c226e31b1882e96c8a7a080114aea90aacdb0bb77331fc36854f79fe118fabd119f278bc20b94d3693bcc69d7382bc6e4d2f1e91c042b41eb660d2214e75c45d
@@ -1,11 +1,11 @@
1
1
  PATH
2
2
  remote: ../hyper-component
3
3
  specs:
4
- hyper-component (1.0.alpha1.1)
5
- hyper-state (= 1.0.alpha1.1)
6
- hyperstack-config (= 1.0.alpha1.1)
7
- libv8 (~> 6.3.0)
8
- mini_racer (~> 0.1.15)
4
+ hyper-component (1.0.alpha1.3)
5
+ hyper-state (= 1.0.alpha1.3)
6
+ hyperstack-config (= 1.0.alpha1.3)
7
+ libv8 (~> 6.7.0)
8
+ mini_racer (~> 0.2.4)
9
9
  opal (>= 0.11.0, < 0.12.0)
10
10
  opal-activesupport (~> 0.3.1)
11
11
  react-rails (>= 2.4.0, < 2.5.0)
@@ -13,26 +13,26 @@ PATH
13
13
  PATH
14
14
  remote: ../hyper-operation
15
15
  specs:
16
- hyper-operation (1.0.alpha1.1)
16
+ hyper-operation (1.0.alpha1.3)
17
17
  activerecord (>= 4.0.0)
18
- hyper-component (= 1.0.alpha1.1)
18
+ hyper-component (= 1.0.alpha1.3)
19
19
  mutations
20
20
  opal-activesupport (~> 0.3.1)
21
+ tty-table
21
22
 
22
23
  PATH
23
24
  remote: ../hyper-state
24
25
  specs:
25
- hyper-state (1.0.alpha1.1)
26
- hyperstack-config (= 1.0.alpha1.1)
26
+ hyper-state (1.0.alpha1.3)
27
+ hyperstack-config (= 1.0.alpha1.3)
27
28
  opal (>= 0.11.0, < 0.12.0)
28
29
 
29
30
  PATH
30
31
  remote: ../hyperstack-config
31
32
  specs:
32
- hyperstack-config (1.0.alpha1.1)
33
- libv8 (~> 6.3.0)
33
+ hyperstack-config (1.0.alpha1.3)
34
34
  listen (~> 3.0)
35
- mini_racer (~> 0.1.15)
35
+ mini_racer (~> 0.2.4)
36
36
  opal (>= 0.11.0, < 0.12.0)
37
37
  opal-browser (~> 0.2.0)
38
38
  uglifier
@@ -41,11 +41,11 @@ PATH
41
41
  PATH
42
42
  remote: .
43
43
  specs:
44
- hyper-model (1.0.alpha1.1)
44
+ hyper-model (1.0.alpha1.3)
45
45
  activemodel
46
46
  activerecord (>= 4.0.0)
47
- hyper-component (= 1.0.alpha1.1)
48
- hyper-operation (= 1.0.alpha1.1)
47
+ hyper-component (= 1.0.alpha1.3)
48
+ hyper-operation (= 1.0.alpha1.3)
49
49
 
50
50
  GEM
51
51
  remote: https://rubygems.org/
@@ -141,6 +141,7 @@ GEM
141
141
  eventmachine (>= 0.12.9)
142
142
  http_parser.rb (~> 0.6.0)
143
143
  equalizer (0.0.11)
144
+ equatable (0.5.0)
144
145
  erubi (1.7.1)
145
146
  eventmachine (1.2.7)
146
147
  execjs (2.7.0)
@@ -164,7 +165,7 @@ GEM
164
165
  rails-dom-testing (>= 1, < 3)
165
166
  railties (>= 4.2.0)
166
167
  thor (>= 0.14, < 2.0)
167
- libv8 (6.3.292.48.1)
168
+ libv8 (6.7.288.46.1)
168
169
  listen (3.1.5)
169
170
  rb-fsevent (~> 0.9, >= 0.9.4)
170
171
  rb-inotify (~> 0.9, >= 0.9.7)
@@ -182,13 +183,14 @@ GEM
182
183
  mimemagic (0.3.2)
183
184
  mini_mime (1.0.1)
184
185
  mini_portile2 (2.3.0)
185
- mini_racer (0.1.15)
186
- libv8 (~> 6.3)
186
+ mini_racer (0.2.4)
187
+ libv8 (>= 6.3)
187
188
  minitest (5.11.3)
188
189
  multi_json (1.13.1)
189
190
  mutations (0.8.3)
190
191
  activesupport
191
192
  mysql2 (0.5.2)
193
+ necromancer (0.4.0)
192
194
  nio4r (2.3.1)
193
195
  nokogiri (1.8.4)
194
196
  mini_portile2 (~> 2.3.0)
@@ -220,6 +222,9 @@ GEM
220
222
  parallel (1.12.1)
221
223
  parser (2.3.3.1)
222
224
  ast (~> 2.2)
225
+ pastel (0.7.2)
226
+ equatable (~> 0.5.0)
227
+ tty-color (~> 0.4.0)
223
228
  powerpack (0.1.2)
224
229
  procto (0.0.3)
225
230
  pry (0.11.3)
@@ -271,8 +276,8 @@ GEM
271
276
  rake
272
277
  rake (12.3.1)
273
278
  rb-fsevent (0.10.3)
274
- rb-inotify (0.9.10)
275
- ffi (>= 0.5.0, < 2)
279
+ rb-inotify (0.10.0)
280
+ ffi (~> 1.0)
276
281
  react-rails (2.4.7)
277
282
  babel-transpiler (>= 0.7.0)
278
283
  connection_pool
@@ -343,6 +348,11 @@ GEM
343
348
  activesupport (>= 4.0)
344
349
  sprockets (>= 3.0.0)
345
350
  sqlite3 (1.3.13)
351
+ strings (0.1.4)
352
+ strings-ansi (~> 0.1.0)
353
+ unicode-display_width (~> 1.4.0)
354
+ unicode_utils (~> 1.4.0)
355
+ strings-ansi (0.1.0)
346
356
  thin (1.7.2)
347
357
  daemons (~> 1.0, >= 1.0.9)
348
358
  eventmachine (~> 1.0, >= 1.0.4)
@@ -351,11 +361,20 @@ GEM
351
361
  thread_safe (0.3.6)
352
362
  tilt (2.0.8)
353
363
  timecop (0.8.1)
364
+ tty-color (0.4.3)
365
+ tty-screen (0.6.5)
366
+ tty-table (0.10.0)
367
+ equatable (~> 0.5.0)
368
+ necromancer (~> 0.4.0)
369
+ pastel (~> 0.7.2)
370
+ strings (~> 0.1.0)
371
+ tty-screen (~> 0.6.4)
354
372
  tzinfo (1.2.5)
355
373
  thread_safe (~> 0.1)
356
- uglifier (4.1.19)
374
+ uglifier (4.1.20)
357
375
  execjs (>= 0.3.0, < 3)
358
376
  unicode-display_width (1.4.0)
377
+ unicode_utils (1.4.0)
359
378
  unparser (0.2.8)
360
379
  abstract_type (~> 0.0.7)
361
380
  adamantium (~> 0.2.0)
@@ -375,7 +394,7 @@ PLATFORMS
375
394
  ruby
376
395
 
377
396
  DEPENDENCIES
378
- bundler
397
+ bundler (>= 1.17.3, < 2.1)
379
398
  capybara
380
399
  chromedriver-helper (= 1.2.0)
381
400
  database_cleaner
@@ -385,8 +404,8 @@ DEPENDENCIES
385
404
  hyper-operation!
386
405
  hyper-state!
387
406
  hyperstack-config!
388
- libv8 (~> 6.3.0)
389
- mini_racer (~> 0.1.15)
407
+ libv8
408
+ mini_racer (~> 0.2.4)
390
409
  mysql2
391
410
  opal-activesupport (~> 0.3.1)
392
411
  opal-browser (~> 0.2.0)
@@ -418,4 +437,4 @@ DEPENDENCIES
418
437
  unparser
419
438
 
420
439
  BUNDLED WITH
421
- 1.16.1
440
+ 2.0.1
data/Rakefile CHANGED
@@ -1,6 +1,18 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
3
 
4
+ task :part1 do
5
+ (1..2).each { |batch| Rake::Task["spec:batch#{batch}"].invoke rescue nil }
6
+ end
7
+
8
+ task :part2 do
9
+ (3..4).each { |batch| Rake::Task["spec:batch#{batch}"].invoke rescue nil }
10
+ end
11
+
12
+ task :part3 do
13
+ (5..7).each { |batch| Rake::Task["spec:batch#{batch}"].invoke rescue nil }
14
+ end
15
+
4
16
  task :spec do
5
17
  (1..7).each { |batch| Rake::Task["spec:batch#{batch}"].invoke rescue nil }
6
18
  end
@@ -29,11 +29,11 @@ Gem::Specification.new do |spec|
29
29
  spec.add_dependency 'activerecord', '>= 4.0.0'
30
30
  spec.add_dependency 'hyper-component', HyperModel::VERSION
31
31
  spec.add_dependency 'hyper-operation', HyperModel::VERSION
32
- spec.add_development_dependency 'bundler'
32
+ spec.add_development_dependency 'bundler', ['>= 1.17.3', '< 2.1']
33
33
  spec.add_development_dependency 'capybara'
34
34
  spec.add_development_dependency 'chromedriver-helper', '1.2.0'
35
- spec.add_development_dependency 'libv8', '~> 6.3.0' # see https://github.com/discourse/mini_racer/issues/92
36
- spec.add_development_dependency 'mini_racer', '~> 0.1.15'
35
+ spec.add_development_dependency 'libv8'
36
+ spec.add_development_dependency 'mini_racer', '~> 0.2.4'
37
37
  spec.add_development_dependency 'selenium-webdriver'
38
38
  spec.add_development_dependency 'database_cleaner'
39
39
  spec.add_development_dependency 'factory_bot_rails'
@@ -29,7 +29,7 @@ module ActiveRecord
29
29
  class ReactiveRecordPsuedoRelationArray < Array
30
30
  attr_accessor :__synchromesh_permission_granted
31
31
  attr_accessor :acting_user
32
- def __secure_collection_check(_acting_user)
32
+ def __secure_collection_check(*)
33
33
  self
34
34
  end
35
35
  end
@@ -39,11 +39,13 @@ module ActiveRecord
39
39
  class Relation
40
40
  attr_accessor :__synchromesh_permission_granted
41
41
  attr_accessor :acting_user
42
- def __secure_collection_check(acting_user)
42
+
43
+ def __secure_collection_check(cache_item)
43
44
  return self if __synchromesh_permission_granted
44
- return self if __secure_remote_access_to_all(self, acting_user).__synchromesh_permission_granted
45
- return self if __secure_remote_access_to_unscoped(self, acting_user).__synchromesh_permission_granted
46
- Hyperstack::InternalPolicy.raise_operation_access_violation(:scoped_permission_not_granted, "Last relation: #{self}, acting_user: #{acting_user}")
45
+ return self if __secure_remote_access_to_all(self, cache_item.acting_user).__synchromesh_permission_granted
46
+ return self if __secure_remote_access_to_unscoped(self, cache_item.acting_user).__synchromesh_permission_granted
47
+ Hyperstack::InternalPolicy.raise_operation_access_violation(
48
+ :scoped_permission_not_granted, "Access denied for #{cache_item}")
47
49
  end
48
50
  end
49
51
  # Monkey patches and extensions to base
@@ -90,6 +92,9 @@ module ActiveRecord
90
92
  this.acting_user = old
91
93
  end
92
94
  end
95
+ singleton_class.send(:define_method, "_#{name}") do |*args|
96
+ all.instance_exec(*args, &block)
97
+ end
93
98
  singleton_class.send(:define_method, name) do |*args|
94
99
  all.instance_exec(*args, &block)
95
100
  end
@@ -1,3 +1,3 @@
1
1
  module HyperModel
2
- VERSION = '1.0.alpha1.2'
2
+ VERSION = '1.0.alpha1.3'
3
3
  end
@@ -44,7 +44,7 @@ module ActiveRecord
44
44
  @owner_class = owner_class
45
45
  @macro = macro
46
46
  @options = options
47
- @klass_name = options[:class_name] || (collection? && name.camelize.sub(/s$/, '')) || name.camelize
47
+ @klass_name = options[:class_name] || (collection? && name.camelize.singularize) || name.camelize
48
48
  @association_foreign_key = options[:foreign_key] || (macro == :belongs_to && "#{name}_id") || "#{@owner_class.name.underscore}_id"
49
49
  @source = options[:source] || @klass_name.underscore if options[:through]
50
50
  @attribute = name
@@ -97,9 +97,15 @@ module ActiveRecord
97
97
  next if association.attribute == attribute
98
98
  return association if klass == association.owner_class
99
99
  end
100
- raise "Association #{@owner_class}.#{attribute} "\
101
- "(foreign_key: #{@association_foreign_key}) "\
102
- "has no inverse in #{@klass_name}"
100
+ # instead of raising an error go ahead and create the inverse relationship if it does not exist.
101
+ # https://github.com/hyperstack-org/hyperstack/issues/89
102
+ if macro == :belongs_to
103
+ Hyperstack::Component::IsomorphicHelpers.log "**** warning dynamically adding relationship: #{klass}.has_many :#{@owner_class.name.underscore.pluralize}, foreign_key: #{@association_foreign_key}", :warning
104
+ klass.has_many @owner_class.name.underscore.pluralize, foreign_key: @association_foreign_key
105
+ else
106
+ Hyperstack::Component::IsomorphicHelpers.log "**** warning dynamically adding relationship: #{klass}.belongs_to :#{@owner_class.name.underscore}, foreign_key: #{@association_foreign_key}", :warning
107
+ klass.belongs_to @owner_class.name.underscore, foreign_key: @association_foreign_key
108
+ end
103
109
  end
104
110
 
105
111
  def klass
@@ -261,10 +261,10 @@ module ActiveRecord
261
261
  end
262
262
 
263
263
  def finder_method(name)
264
- ReactiveRecord::ScopeDescription.new(self, "_#{name}", {})
264
+ ReactiveRecord::ScopeDescription.new(self, "_#{name}", {}) # was adding _ to front
265
265
  [name, "#{name}!"].each do |method|
266
266
  singleton_class.send(:define_method, method) do |*vargs|
267
- all.apply_scope("_#{method}", *vargs).first
267
+ all.apply_scope("_#{method}", *vargs).first # was adding _ to front
268
268
  end
269
269
  end
270
270
  end
@@ -52,6 +52,9 @@ module ReactiveRecord
52
52
  def all
53
53
  observed
54
54
  @dummy_collection.notify if @dummy_collection
55
+ # unless false && @collection # this fixes https://github.com/hyperstack-org/hyperstack/issues/82 in very limited cases, and breaks otherthings
56
+ # sync_collection_with_parent
57
+ # end
55
58
  unless @collection
56
59
  @collection = []
57
60
  if ids = ReactiveRecord::Base.fetch_from_db([*@vector, "*all"])
@@ -80,8 +83,15 @@ module ReactiveRecord
80
83
 
81
84
  def ==(other_collection)
82
85
  observed
83
- return !@collection unless other_collection.is_a? Collection
86
+ # handle special case of other_collection NOT being a collection (typically nil)
87
+ return (@collection || []) == other_collection unless other_collection.is_a? Collection
84
88
  other_collection.observed
89
+ # if either collection has not been created then compare the vectors
90
+ # https://github.com/hyperstack-org/hyperstack/issues/81
91
+ # TODO: if this works then remove the || [] below (2 of them)
92
+ if !@collection || !other_collection.collection
93
+ return @vector == other_collection.vector && unsaved_children == other_collection.unsaved_children
94
+ end
85
95
  my_children = (@collection || []).select { |target| target != @dummy_record }
86
96
  if other_collection
87
97
  other_children = (other_collection.collection || []).select { |target| target != other_collection.dummy_record }
@@ -261,11 +271,15 @@ To determine this sync_scopes first asks if the record being changed is in the s
261
271
  end
262
272
 
263
273
  def link_to_parent
264
- return if @linked
274
+ # puts "#{self}.link_to_parent @linked = #{!!@linked}, collection? #{!!@collection}"
275
+ # always check that parent is synced - fixes issue https://github.com/hyperstack-org/hyperstack/issues/82
276
+ # note that sync_collection_with_parent checks to make sure that is NOT a collection and that there IS a parent
277
+
278
+ return sync_collection_with_parent if @linked
265
279
  @linked = true
266
280
  if @parent
267
281
  @parent.link_child self
268
- sync_collection_with_parent unless collection
282
+ sync_collection_with_parent
269
283
  else
270
284
  ReactiveRecord::Base.add_to_outer_scopes self
271
285
  end
@@ -278,14 +292,23 @@ To determine this sync_scopes first asks if the record being changed is in the s
278
292
  end
279
293
 
280
294
  def sync_collection_with_parent
295
+ # puts "#{self}.sync_collection_with_parent"
296
+ return if @collection || !@parent || @parent.dummy_collection # fixes issue https://github.com/hyperstack-org/hyperstack/issues/78 and supports /82
281
297
  if @parent.collection
298
+ # puts ">>> @parent.collection present"
282
299
  if @parent.collection.empty?
300
+ # puts ">>>>> @parent.collection is empty!"
283
301
  @collection = []
284
302
  elsif filter?
285
- @collection = filter_records(@parent.collection)
303
+ # puts "#{self}.sync_collection_with_parent (@parent = #{@parent}) calling filter records on (#{@parent.collection})"
304
+ @collection = filter_records(@parent.collection) # .tap { |rr| puts "returns #{rr} #{rr.to_a}" }
286
305
  end
287
- elsif @parent._count_internal(false).zero? # just changed this from count.zero?
306
+ elsif !@linked && @parent._count_internal(false).zero?
307
+ # don't check _count_internal if already linked as this cause an unnecessary rendering cycle
308
+ # puts ">>> @parent._count_internal(false).zero? is true!"
288
309
  @count = 0
310
+ else
311
+ # puts ">>> NOP"
289
312
  end
290
313
  end
291
314
 
@@ -327,7 +350,9 @@ To determine this sync_scopes first asks if the record being changed is in the s
327
350
  # when count is called on a leaf, count_internal is called for each
328
351
  # ancestor. Only the outermost count has load_from_client == true
329
352
  observed
330
- if @collection
353
+ if @count && @dummy_collection
354
+ @count # fixes https://github.com/hyperstack-org/hyperstack/issues/79
355
+ elsif @collection
331
356
  @collection.count
332
357
  elsif @count ||= ReactiveRecord::Base.fetch_from_db([*@vector, "*count"])
333
358
  @count
@@ -10,6 +10,7 @@ module ReactiveRecord
10
10
  if RUBY_ENGINE != 'opal'
11
11
  @server_data_cache = ReactiveRecord::ServerDataCache.new(context.controller.acting_user, {})
12
12
  else
13
+ Hyperstack::Internal::State::Variable.set(WhileLoading, :quiet, true)
13
14
  @public_columns_hash = get_public_columns_hash
14
15
  define_attribute_methods
15
16
  @outer_scopes = Set.new
@@ -242,7 +243,7 @@ module ReactiveRecord
242
243
  end if record.new? || record.changed? || (record == record_being_saved && force)
243
244
  record_index += 1
244
245
  end
245
- [models, associations, backing_records]
246
+ [models.sort_by { |model| model[:id] }, associations, backing_records]
246
247
  end
247
248
 
248
249
  def save_or_validate(save, validate, force, &block)
@@ -316,21 +317,23 @@ module ReactiveRecord
316
317
 
317
318
  else
318
319
 
319
- def self.find_record(model, id, vector, save)
320
+ def self.find_record(model, id, acting_user, vector, save)
320
321
  if !save
321
322
  found = vector[1..-1].inject(vector[0]) do |object, method|
322
323
  if object.nil? # happens if you try to do an all on empty scope followed by more scopes
323
324
  object
324
- elsif method.is_a? Array
325
+ elsif method.is_a? Array #__secure_remote_access_to_
325
326
  if method[0] == 'new'
326
327
  object.new
327
- else
328
+ elsif method[0] == 'find_by'
328
329
  object.send(*method)
330
+ else
331
+ object.send(:"__secure_remote_access_to_#{method[0]}", object, acting_user, *method[1..-1])
329
332
  end
330
- elsif method.is_a? String and method[0] == '*'
333
+ elsif method.is_a?(String) && method[0] == '*'
331
334
  object[method.gsub(/^\*/,'').to_i]
332
335
  else
333
- object.send(method)
336
+ object.send(:"__secure_remote_access_to_#{method}", object, acting_user)
334
337
  end
335
338
  end
336
339
  if id and (found.nil? or !(found.class <= model) or (found.id and found.id.to_s != id.to_s))
@@ -362,13 +365,13 @@ module ReactiveRecord
362
365
  id = attributes.delete(model.primary_key) if model.respond_to? :primary_key # if we are saving existing model primary key value will be present
363
366
  vector = model_to_save[:vector]
364
367
  vector = [vector[0].constantize] + vector[1..-1].collect do |method|
365
- if method.is_a?(Array) and method.first == "find_by_id"
368
+ if method.is_a?(Array) && method.first == "find_by_id"
366
369
  ["find", method.last]
367
370
  else
368
371
  method
369
372
  end
370
373
  end
371
- reactive_records[model_to_save[:id]] = vectors[vector] = record = find_record(model, id, vector, save) # ??? || validate ???
374
+ reactive_records[model_to_save[:id]] = vectors[vector] = record = find_record(model, id, acting_user, vector, save) # ??? || validate ???
372
375
  next unless record
373
376
  if attributes.empty?
374
377
  dont_save_list << record unless save
@@ -507,7 +510,7 @@ module ReactiveRecord
507
510
  if save || validate
508
511
  {success: false, saved_models: saved_models, message: e}
509
512
  else
510
- {}
513
+ raise e # was returning {} TODO verify that just raising the error at least reports the error
511
514
  end
512
515
  end
513
516
 
@@ -65,8 +65,9 @@ module ReactiveRecord
65
65
  ]
66
66
  end
67
67
  failed do |e|
68
- # AccessViolations are already sent to on_error
69
- Hyperstack.on_error(e, :fetch_error, params.to_h) unless e.is_a? Hyperstack::AccessViolation
68
+ e.define_singleton_method(:__hyperstack_on_error) do |operation, params, fmted_message|
69
+ Hyperstack.on_error(operation, self, params, fmted_message)
70
+ end
70
71
  raise e
71
72
  end
72
73
  end
@@ -9,7 +9,10 @@ module ReactiveRecord
9
9
  def set_pre_sync_related_records(related_records, _record = nil)
10
10
  @pre_sync_related_records = nil
11
11
  ReactiveRecord::Base.catch_db_requests do
12
+ puts "#{self}.set_pre_sync_related_records filter_records(#{related_records})"
13
+
12
14
  @pre_sync_related_records = filter_records(related_records)
15
+ puts "returns #{@pre_sync_related_records}"
13
16
  live_scopes.each do |scope|
14
17
  scope.set_pre_sync_related_records(@pre_sync_related_records)
15
18
  end
@@ -32,7 +35,9 @@ module ReactiveRecord
32
35
  if collector?
33
36
  update_collector_scope(related_records)
34
37
  else
38
+ puts "#{self}.update_collection calling filter_records(#{related_records})"
35
39
  related_records = filter_records(related_records)
40
+ puts "returns #{related_records}"
36
41
  update_filter_scope(@pre_sync_related_records, related_records)
37
42
  end
38
43
  end
@@ -41,7 +46,8 @@ module ReactiveRecord
41
46
  current = Set.new([*@collection])
42
47
  (related_records - @pre_sync_related_records).each { |r| current << r }
43
48
  (@pre_sync_related_records - related_records).each { |r| current.delete(r) }
44
- replace(filter_records(current))
49
+ puts "#{self}.update_collector_scope calling replace(filter_records(#{current}))"
50
+ replace(filter_records(current).tap { |rr| puts "returns #{rr}" })
45
51
  Set.new([*@collection])
46
52
  end
47
53
 
@@ -74,6 +74,191 @@ module ReactiveRecord
74
74
  # To notify React that something is loading use React::WhileLoading.loading!
75
75
  # once everything is loaded then do React::WhileLoading.loaded_at message (typically a time stamp just for debug purposes)
76
76
 
77
+ # class WhileLoading
78
+ #
79
+ # include Hyperstack::Component::IsomorphicHelpers
80
+ #
81
+ # before_first_mount do
82
+ # @css_to_preload = ""
83
+ # @while_loading_counter = 0
84
+ # end
85
+ #
86
+ # def self.get_next_while_loading_counter
87
+ # @while_loading_counter += 1
88
+ # end
89
+ #
90
+ # def self.preload_css(css)
91
+ # @css_to_preload += "#{css}\n"
92
+ # end
93
+ #
94
+ # def self.has_observers?
95
+ # Hyperstack::Internal::State::Variable.observed?(self, :loaded_at)
96
+ # end
97
+ #
98
+ # class << self
99
+ # alias :observed? :has_observers?
100
+ # end
101
+ #
102
+ # prerender_footer do
103
+ # "<style>\n#{@css_to_preload}\n</style>".tap { @css_to_preload = ""}
104
+ # end
105
+ #
106
+ # if RUBY_ENGINE == 'opal'
107
+ #
108
+ # # +: I DONT THINK WE USE opal-jquery in this module anymore - require 'opal-jquery' if opal_client?
109
+ # # -: You think wrong. add_style_sheet uses the jQuery $, after_mount too, others too
110
+ # # -: I removed those references. Now you think right.
111
+ #
112
+ # include Hyperstack::Component
113
+ #
114
+ # param :render_original_child
115
+ # param :loading
116
+ #
117
+ # class << self
118
+ #
119
+ # def loading?
120
+ # @is_loading
121
+ # end
122
+ #
123
+ # def loading!
124
+ # Hyperstack::Internal::Component::RenderingContext.waiting_on_resources = true
125
+ # Hyperstack::Internal::State::Variable.get(self, :loaded_at)
126
+ # # this was moved to where the fetch is actually pushed on to the fetch array in isomorphic base
127
+ # # Hyperstack::Internal::State::Variable.set(self, :quiet, false)
128
+ # @is_loading = true
129
+ # end
130
+ #
131
+ # def loaded_at(loaded_at)
132
+ # Hyperstack::Internal::State::Variable.set(self, :loaded_at, loaded_at)
133
+ # @is_loading = false
134
+ # end
135
+ #
136
+ # def quiet?
137
+ # Hyperstack::Internal::State::Variable.get(self, :quiet)
138
+ # end
139
+ #
140
+ # def page_loaded?
141
+ # Hyperstack::Internal::State::Variable.get(self, :page_loaded)
142
+ # end
143
+ #
144
+ # def quiet!
145
+ # Hyperstack::Internal::State::Variable.set(self, :quiet, true)
146
+ # after(1) { Hyperstack::Internal::State::Variable.set(self, :page_loaded, true) } unless on_opal_server? or @page_loaded
147
+ # @page_loaded = true
148
+ # end
149
+ #
150
+ # def add_style_sheet
151
+ # # directly assigning the code to the variable triggers a opal 0.10.5 compiler bug.
152
+ # unless @style_sheet_added
153
+ # %x{
154
+ # var style_el = document.createElement("style");
155
+ # style_el.setAttribute("type", "text/css");
156
+ # style_el.innerHTML = ".reactive_record_is_loading > .reactive_record_show_when_loaded { display: none !important; }\n" +
157
+ # ".reactive_record_is_loaded > .reactive_record_show_while_loading { display: none !important; }";
158
+ # document.head.append(style_el);
159
+ # }
160
+ # @style_sheet_added = true
161
+ # end
162
+ # end
163
+ #
164
+ # end
165
+ #
166
+ # def after_mount_and_update
167
+ # @waiting_on_resources = @Loading
168
+ # node = dom_node
169
+ # %x{
170
+ # Array.from(node.children).forEach(
171
+ # function(current_node, current_index, list_obj) {
172
+ # if (current_index > 0 && current_node.className.indexOf('reactive_record_show_when_loaded') === -1) {
173
+ # current_node.className = current_node.className + ' reactive_record_show_when_loaded';
174
+ # } else if (current_index == 0 && current_node.className.indexOf('reactive_record_show_while_loading') === -1) {
175
+ # current_node.className = current_node.className + ' reactive_record_show_while_loading';
176
+ # }
177
+ # }
178
+ # );
179
+ # }
180
+ # nil
181
+ # end
182
+ #
183
+ # before_mount do
184
+ # @uniq_id = WhileLoading.get_next_while_loading_counter
185
+ # WhileLoading.preload_css(
186
+ # ":not(.reactive_record_is_loading).reactive_record_while_loading_container_#{@uniq_id} > :nth-child(1) {\n"+
187
+ # " display: none;\n"+
188
+ # "}\n"
189
+ # )
190
+ # end
191
+ #
192
+ # after_mount do
193
+ # WhileLoading.add_style_sheet
194
+ # after_mount_and_update
195
+ # end
196
+ #
197
+ # after_update :after_mount_and_update
198
+ #
199
+ # render do
200
+ # @RenderOriginalChild.call(@uniq_id)
201
+ # end
202
+ #
203
+ # end
204
+ #
205
+ # end
206
+ #
207
+ # end
208
+ #
209
+ # module Hyperstack
210
+ # module Component
211
+ #
212
+ # class Element
213
+ #
214
+ # def while_loading(display = "", &loading_display_block)
215
+ # original_block = block || -> () {}
216
+ #
217
+ # if display.respond_to? :as_node
218
+ # display = display.as_node
219
+ # block = lambda { display.render; instance_eval(&original_block) }
220
+ # elsif !loading_display_block
221
+ # block = lambda { display; instance_eval(&original_block) }
222
+ # else
223
+ # block = ->() { instance_eval(&loading_display_block); instance_eval(&original_block) }
224
+ # end
225
+ # loading_child = Internal::Component::RenderingContext.build do |buffer|
226
+ # Hyperstack::Internal::Component::RenderingContext.render(:span, key: 1, &loading_display_block) #{ to_s }
227
+ # buffer.dup
228
+ # end
229
+ # children = `#{@native}.props.children.slice(0)`
230
+ # children.unshift(loading_child[0].instance_eval { @native })
231
+ # @native = `React.cloneElement(#{@native}, #{@properties.shallow_to_n}, #{children})`
232
+ # render_original_child = lambda do |uniq_id|
233
+ # classes = [
234
+ # @properties[:class], @properties[:className],
235
+ # "reactive_record_while_loading_container_#{uniq_id}"
236
+ # ].compact.join(' ')
237
+ # @properties.merge!({
238
+ # "data-reactive_record_while_loading_container_id" => uniq_id,
239
+ # "data-reactive_record_enclosing_while_loading_container_id" => uniq_id,
240
+ # className: classes
241
+ # })
242
+ # @native = `React.cloneElement(#{@native}, #{@properties.shallow_to_n})`
243
+ # render
244
+ # end
245
+ # delete
246
+ # ReactAPI.create_element(
247
+ # ReactiveRecord::WhileLoading,
248
+ # loading: waiting_on_resources,
249
+ # render_original_child: render_original_child)
250
+ # end
251
+ #
252
+ # def hide_while_loading
253
+ # while_loading
254
+ # end
255
+ #
256
+ # end
257
+ # end
258
+ # end
259
+ #
260
+
261
+
77
262
  class WhileLoading
78
263
 
79
264
  include Hyperstack::Component::IsomorphicHelpers
@@ -116,6 +301,7 @@ module ReactiveRecord
116
301
  param :loading_children
117
302
  param :element_type
118
303
  param :element_props
304
+ others :other_props
119
305
  param :display, default: ''
120
306
 
121
307
  class << self
@@ -157,8 +343,8 @@ module ReactiveRecord
157
343
  %x{
158
344
  var style_el = document.createElement("style");
159
345
  style_el.setAttribute("type", "text/css");
160
- style_el.innerHTML = ".reactive_record_is_loading > .reactive_record_show_when_loaded { display: none; }\n" +
161
- ".reactive_record_is_loaded > .reactive_record_show_while_loading { display: none; }";
346
+ style_el.innerHTML = ".reactive_record_is_loading > .reactive_record_show_when_loaded { display: none !important; }\n" +
347
+ ".reactive_record_is_loaded > .reactive_record_show_while_loading { display: none !important; }";
162
348
  document.head.append(style_el);
163
349
  }
164
350
  @style_sheet_added = true
@@ -167,53 +353,57 @@ module ReactiveRecord
167
353
 
168
354
  end
169
355
 
170
- before_mount do
171
- @uniq_id = WhileLoading.get_next_while_loading_counter
172
- WhileLoading.preload_css(
173
- ".reactive_record_while_loading_container_#{@uniq_id} > :nth-child(1n+#{@LoadedChildren.count+1}) {\n"+
174
- " display: none;\n"+
175
- "}\n"
176
- )
177
- end
178
-
179
- after_mount do
356
+ def after_mount_and_update
180
357
  @waiting_on_resources = @Loading
181
- WhileLoading.add_style_sheet
182
358
  node = dom_node
183
359
  %x{
184
- var nodes = node.querySelectorAll(':nth-child(-1n+'+#{@LoadedChildren.count}+')');
185
- nodes.forEach(
360
+ Array.from(node.children).forEach(
186
361
  function(current_node, current_index, list_obj) {
187
- if (current_node.className.indexOf('reactive_record_show_when_loaded') === -1) {
362
+ if (current_index > 0 && current_node.className.indexOf('reactive_record_show_when_loaded') === -1) {
188
363
  current_node.className = current_node.className + ' reactive_record_show_when_loaded';
189
- }
190
- }
191
- );
192
- nodes = node.querySelectorAll(':nth-child(1n+'+#{@LoadedChildren.count+1}+')');
193
- nodes.forEach(
194
- function(current_node, current_index, list_obj) {
195
- if (current_node.className.indexOf('reactive_record_show_while_loading') === -1) {
364
+ } else if (current_index == 0 && current_node.className.indexOf('reactive_record_show_while_loading') === -1) {
196
365
  current_node.className = current_node.className + ' reactive_record_show_while_loading';
197
366
  }
198
367
  }
199
368
  );
200
369
  }
370
+ nil
201
371
  end
202
372
 
203
- after_update do
204
- @waiting_on_resources = @Loading
373
+ before_mount do
374
+ @uniq_id = WhileLoading.get_next_while_loading_counter
375
+ WhileLoading.preload_css(
376
+ ":not(.reactive_record_is_loading).reactive_record_while_loading_container_#{@uniq_id} > :nth-child(1) {\n"+
377
+ " display: none;\n"+
378
+ "}\n"
379
+ )
380
+ end
381
+
382
+ after_mount do
383
+ WhileLoading.add_style_sheet
384
+ after_mount_and_update
205
385
  end
206
386
 
387
+ after_update :after_mount_and_update
388
+
207
389
  render do
390
+ # return ReactAPI.create_element(@ElementType[0], @ElementProps.dup) do
391
+ # @LoadedChildren
392
+ # end
208
393
  props = @ElementProps.dup
209
- classes = [props[:class], props[:className], "reactive_record_while_loading_container_#{@uniq_id}"].compact.join(" ")
394
+ classes = [
395
+ props[:class], props[:className],
396
+ @OtherProps.delete(:class), @OtherProps.delete(:className),
397
+ "reactive_record_while_loading_container_#{@uniq_id}"
398
+ ].compact.join(" ")
210
399
  props.merge!({
211
400
  "data-reactive_record_while_loading_container_id" => @uniq_id,
212
401
  "data-reactive_record_enclosing_while_loading_container_id" => @uniq_id,
213
402
  class: classes
214
403
  })
404
+ props.merge!(@OtherProps)
215
405
  ReactAPI.create_element(@ElementType[0], props) do
216
- @LoadedChildren + @LoadingChildren
406
+ @LoadingChildren + @LoadedChildren
217
407
  end.tap { |e| e.waiting_on_resources = @Loading }
218
408
  end
219
409
 
@@ -231,6 +421,10 @@ module Hyperstack
231
421
  def while_loading(display = "", &loading_display_block)
232
422
  loaded_children = []
233
423
  loaded_children = block.call.dup if block
424
+ if loaded_children.last.is_a? String
425
+ loaded_children <<
426
+ Hyperstack::Internal::Component::ReactWrapper.create_element(:span) { loaded_children.pop }
427
+ end
234
428
  if display.respond_to? :as_node
235
429
  display = display.as_node
236
430
  loading_display_block = lambda { display.render }
@@ -238,12 +432,10 @@ module Hyperstack
238
432
  loading_display_block = lambda { display }
239
433
  end
240
434
  loading_children = Internal::Component::RenderingContext.build do |buffer|
241
- result = loading_display_block.call
242
- result = result.to_s if result.try :acts_as_string?
243
- result.span.tap { |e| e.waiting_on_resources = Internal::Component::RenderingContext.waiting_on_resources } if result.is_a? String
435
+ Hyperstack::Internal::Component::RenderingContext.render(:span, &loading_display_block) #{ to_s }
244
436
  buffer.dup
245
437
  end
246
-
438
+ as_node
247
439
  new_element = ReactAPI.create_element(
248
440
  ReactiveRecord::WhileLoading,
249
441
  loading: waiting_on_resources,
@@ -252,7 +444,7 @@ module Hyperstack
252
444
  element_type: [type],
253
445
  element_props: properties)
254
446
 
255
- Internal::Component::RenderingContext.replace(self, new_element)
447
+ #Internal::Component::RenderingContext.replace(self, new_element)
256
448
  end
257
449
 
258
450
  def hide_while_loading
@@ -267,6 +459,10 @@ if RUBY_ENGINE == 'opal'
267
459
  module Hyperstack
268
460
  module Component
269
461
 
462
+ def quiet?
463
+ Hyperstack::Internal::State::Variable.get(ReactiveRecord::WhileLoading, :quiet)
464
+ end
465
+
270
466
  alias_method :original_component_did_mount, :component_did_mount
271
467
 
272
468
  def component_did_mount(*args)
@@ -2,9 +2,12 @@ module ReactiveRecord
2
2
  class Broadcast
3
3
 
4
4
  def self.after_commit(operation, model)
5
+ # Calling public_columns_hash once insures all policies are loaded
6
+ # before the first broadcast.
7
+ @public_columns_hash ||= ActiveRecord::Base.public_columns_hash
5
8
  Hyperstack::InternalPolicy.regulate_broadcast(model) do |data|
6
9
  if !Hyperstack.on_server? && Hyperstack::Connection.root_path
7
- send_to_server(operation, data) rescue nil # server no longer running so ignore
10
+ send_to_server(operation, data) rescue nil # fails if server no longer running so ignore
8
11
  else
9
12
  SendPacket.run(data, operation: operation)
10
13
  end
@@ -90,7 +90,7 @@ class ActiveRecord::Base
90
90
  def belongs_to(attr_name, *args)
91
91
  belongs_to_without_reactive_record_add_is_method(attr_name, *args).tap do
92
92
  define_method "#{attr_name}_is?".to_sym do |model|
93
- self.class.reflections[attr_name].foreign_key == model.id
93
+ self.class.reflections[attr_name.to_s].foreign_key == model.id
94
94
  end
95
95
  end
96
96
  end
@@ -103,7 +103,19 @@ class ActiveRecord::Base
103
103
  self.acting_user = old
104
104
  self
105
105
  else
106
- Hyperstack::InternalPolicy.raise_operation_access_violation(:crud_access_violation, "for #{self} - #{permission}(#{args}) acting_user: #{user}")
106
+ acting_user_string =
107
+ if acting_user
108
+ id = user.respond_to?(:id) ? user.id : user
109
+ "not allowed for acting_user: <##{user.class} id: #{user}>"
110
+ else
111
+ "not allowed without acting_user (acting_user = nil)"
112
+ end
113
+
114
+ message = "CRUD access violation: <##{self.class} id: #{self.id}> - #{permission}(#{args}) #{acting_user_string}"
115
+ if permission == :view_permitted?
116
+ details = Hyperstack::PolicyDiagnostics.policy_dump_for(self, user)
117
+ end
118
+ Hyperstack::InternalPolicy.raise_operation_access_violation(message, details || '')
107
119
  end
108
120
  end
109
121
 
@@ -229,6 +229,26 @@ module ReactiveRecord
229
229
  @db_cache.add_item_to_cache self
230
230
  end
231
231
 
232
+ def to_s
233
+ acting_user_string =
234
+ if acting_user
235
+ " - with acting user: <#{acting_user.class.name} id: #{acting_user.id}>"
236
+ else
237
+ ' - with no acting user'
238
+ end
239
+ vector.collect do |e|
240
+ if e.is_a? String
241
+ e
242
+ elsif e.is_a? Array
243
+ e.length > 1 ? "#{e.first}(#{e[1..-1].join(', ')})" : e.first
244
+ else
245
+ e.name
246
+ end
247
+ end.join('.') + acting_user_string
248
+ rescue
249
+ vector.to_s + acting_user_string
250
+ end
251
+
232
252
  def start_timing(&block)
233
253
  ServerDataCache.class.start_timing(&block)
234
254
  end
@@ -245,11 +265,11 @@ module ReactiveRecord
245
265
  cache_item.apply_star || representative
246
266
  elsif method == "*all"
247
267
  # if we secure the collection then we assume its okay to read the ids
248
- secured_value = cache_item.value.__secure_collection_check(@acting_user)
268
+ secured_value = cache_item.value.__secure_collection_check(cache_item)
249
269
  cache_item.build_new_cache_item(timing(:active_record) { secured_value.collect { |record| record.id } }, method, method)
250
270
  elsif method == "*count"
251
- secured_value = cache_item.value.__secure_collection_check(@acting_user)
252
- cache_item.build_new_cache_item(timing(:active_record) { cache_item.value.__secure_collection_check(@acting_user).count }, method, method)
271
+ secured_value = cache_item.value.__secure_collection_check(cache_item)
272
+ cache_item.build_new_cache_item(timing(:active_record) { cache_item.value.__secure_collection_check(cache_item).count }, method, method)
253
273
  elsif preloaded_value = @preloaded_records[cache_item.absolute_vector + [method]]
254
274
  # no security check needed since we already evaluated this
255
275
  cache_item.build_new_cache_item(preloaded_value, method, method)
@@ -273,10 +293,10 @@ module ReactiveRecord
273
293
  else
274
294
  raise "method missing"
275
295
  end
276
- rescue Exception => e # this check may no longer be needed as we are quite explicit now on which methods we apply
277
- # ReactiveRecord::Pry::rescued(e)
278
- ::Rails.logger.debug "\033[0;31;1mERROR: HyperModel exception caught when applying #{method} to db object #{cache_item.value}: #{e}\033[0;30;21m"
279
- raise e, "HyperModel fetching records failed, exception caught when applying #{method} to db object #{cache_item.value}: #{e}", e.backtrace
296
+ # rescue Exception => e # this check may no longer be needed as we are quite explicit now on which methods we apply
297
+ # # ReactiveRecord::Pry::rescued(e)
298
+ # #::Rails.logger.debug "\033[0;31;1mERROR: HyperModel exception caught when applying #{method} to db object #{cache_item.value}: #{e}\033[0;30;21m"
299
+ # raise e, "HyperModel fetching records failed, exception caught when applying #{method} to db object #{cache_item.value}: #{e}", e.backtrace
280
300
  end
281
301
  end
282
302
  end
@@ -296,7 +316,7 @@ module ReactiveRecord
296
316
  end
297
317
 
298
318
  def apply_star
299
- if @value && @value.__secure_collection_check(@acting_user) && @value.length > 0
319
+ if @value && @value.__secure_collection_check(self) && @value.length > 0
300
320
  i = -1
301
321
  @value.inject(nil) do |representative, current_value|
302
322
  i += 1
@@ -0,0 +1,3 @@
1
+ rspec ./spec/batch5/save_while_loading_spec.rb:28 # save while loading with push
2
+ rspec ./spec/batch4/default_value_spec.rb:40 # defaultValue special handling will not use the defaultValue param until data is loaded - unit test
3
+ rspec ./spec/batch3/revert_spec.rb:39 # reverting records adds the todo to adam's todos and expects adam to change
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hyper-model
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.alpha1.2
4
+ version: 1.0.alpha1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mitch VanDuyn
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-11-16 00:00:00.000000000 Z
12
+ date: 2019-01-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activemodel
@@ -45,42 +45,48 @@ dependencies:
45
45
  requirements:
46
46
  - - '='
47
47
  - !ruby/object:Gem::Version
48
- version: 1.0.alpha1.2
48
+ version: 1.0.alpha1.3
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - '='
54
54
  - !ruby/object:Gem::Version
55
- version: 1.0.alpha1.2
55
+ version: 1.0.alpha1.3
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: hyper-operation
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
60
  - - '='
61
61
  - !ruby/object:Gem::Version
62
- version: 1.0.alpha1.2
62
+ version: 1.0.alpha1.3
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - '='
68
68
  - !ruby/object:Gem::Version
69
- version: 1.0.alpha1.2
69
+ version: 1.0.alpha1.3
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: bundler
72
72
  requirement: !ruby/object:Gem::Requirement
73
73
  requirements:
74
74
  - - ">="
75
75
  - !ruby/object:Gem::Version
76
- version: '0'
76
+ version: 1.17.3
77
+ - - "<"
78
+ - !ruby/object:Gem::Version
79
+ version: '2.1'
77
80
  type: :development
78
81
  prerelease: false
79
82
  version_requirements: !ruby/object:Gem::Requirement
80
83
  requirements:
81
84
  - - ">="
82
85
  - !ruby/object:Gem::Version
83
- version: '0'
86
+ version: 1.17.3
87
+ - - "<"
88
+ - !ruby/object:Gem::Version
89
+ version: '2.1'
84
90
  - !ruby/object:Gem::Dependency
85
91
  name: capybara
86
92
  requirement: !ruby/object:Gem::Requirement
@@ -113,30 +119,30 @@ dependencies:
113
119
  name: libv8
114
120
  requirement: !ruby/object:Gem::Requirement
115
121
  requirements:
116
- - - "~>"
122
+ - - ">="
117
123
  - !ruby/object:Gem::Version
118
- version: 6.3.0
124
+ version: '0'
119
125
  type: :development
120
126
  prerelease: false
121
127
  version_requirements: !ruby/object:Gem::Requirement
122
128
  requirements:
123
- - - "~>"
129
+ - - ">="
124
130
  - !ruby/object:Gem::Version
125
- version: 6.3.0
131
+ version: '0'
126
132
  - !ruby/object:Gem::Dependency
127
133
  name: mini_racer
128
134
  requirement: !ruby/object:Gem::Requirement
129
135
  requirements:
130
136
  - - "~>"
131
137
  - !ruby/object:Gem::Version
132
- version: 0.1.15
138
+ version: 0.2.4
133
139
  type: :development
134
140
  prerelease: false
135
141
  version_requirements: !ruby/object:Gem::Requirement
136
142
  requirements:
137
143
  - - "~>"
138
144
  - !ruby/object:Gem::Version
139
- version: 0.1.15
145
+ version: 0.2.4
140
146
  - !ruby/object:Gem::Dependency
141
147
  name: selenium-webdriver
142
148
  requirement: !ruby/object:Gem::Requirement
@@ -642,6 +648,7 @@ files:
642
648
  - lib/reactive_record/scope_description.rb
643
649
  - lib/reactive_record/serializers.rb
644
650
  - lib/reactive_record/server_data_cache.rb
651
+ - spec_fails.txt
645
652
  homepage: http://ruby-hyperstack.org
646
653
  licenses:
647
654
  - MIT
@@ -661,8 +668,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
661
668
  - !ruby/object:Gem::Version
662
669
  version: 1.3.1
663
670
  requirements: []
664
- rubyforge_project:
665
- rubygems_version: 2.7.8
671
+ rubygems_version: 3.0.2
666
672
  signing_key:
667
673
  specification_version: 4
668
674
  summary: React based CRUD access and Synchronization of active record models across